home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #3 / Amiga Plus CD - 2002 - No. 03.iso / AmiSoft / Util / Misc / Reportplus.lha / reportplus / source / rp.c < prev    next >
C/C++ Source or Header  |  2003-02-14  |  104KB  |  2,900 lines

  1. /* $Filename:    ReportPlus/Source/rp.c
  2.  * $VER:         Report+ 5.65
  3.  * $Description: Multipurpose utility
  4.  *
  5.  * © Copyright 1999-2003 James R. Jacobs. Freely distributable.
  6.  *        _
  7.  *       //      -=AMIGA=-
  8.  *      //
  9.  * _   //
  10.  * \\ //
  11.  *  \X/
  12.  
  13. #INCLUDES -------------------------------------------------------------- */
  14.  
  15. /* #include <assert.h> */
  16.  
  17. #include <exec/types.h>
  18. #include <exec/alerts.h>
  19. #include <exec/nodes.h>
  20. #include <exec/memory.h>
  21. #include <exec/execbase.h>
  22. #include <proto/exec.h>
  23. #include <intuition/intuition.h>
  24. #include <clib/intuition_protos.h>
  25. #include <intuition/gadgetclass.h>
  26. #include <libraries/gadtools.h>
  27. #include <clib/gadtools_protos.h>
  28. #include <libraries/iffparse.h>
  29. #include <workbench/workbench.h> /* struct DiskObject */
  30. #include <libraries/asl.h>
  31. #include <proto/asl.h>
  32. #include <dos/dos.h>
  33. #include <dos/dostags.h>
  34. #include <dos/dosextens.h>
  35. #include <proto/dos.h>
  36. #include <graphics/gfx.h>
  37. #include <graphics/displayinfo.h>
  38. #include <graphics/gels.h>
  39. #include <clib/graphics_protos.h>
  40. #include <utility/tagitem.h>
  41. #include <proto/utility.h>
  42. #include <workbench/icon.h>
  43. #include <clib/icon_protos.h>
  44. #include <clib/alib_protos.h>
  45. #include <resources/battmem.h>
  46. #include <resources/battmembitsamiga.h>
  47. #include <resources/battmembitsshared.h>
  48.  
  49. #define ALL_REACTION_CLASSES
  50. #define ALL_REACTION_MACROS
  51. #include <reaction/reaction.h>
  52. #include <clib/alib_protos.h>
  53. #include <clib/texteditor_protos.h>
  54. #include <gadgets/texteditor.h>
  55. #include <pragmas/texteditor_pragmas.h>
  56.  
  57. #define GID_0_LY1   0
  58. #define GID_0_BU1   1 // the function buttons must start from GID_0_BU1,
  59. #define GID_0_BU2   2 // and must all be consecutive.
  60. #define GID_0_BU3   3
  61. #define GID_0_BU4   4
  62. #define GID_0_BU5   5
  63. #define GID_0_BU6   6
  64. #define GID_0_BU7   7
  65. #define GID_0_BU8   8
  66. #define GID_0_BU9   9
  67. #define GID_0_BU10 10
  68. #define GID_0_ST1  11
  69. #define GIDS_0     GID_0_ST1
  70.  
  71. #define GID_A_LY1  0
  72. #define GIDS_A     GID_A_LY1
  73.  
  74. #include <ctype.h>
  75. #include <stdio.h>          /* FILE, printf() */
  76. #include <stdlib.h>         /* EXIT_SUCCESS, EXIT_FAILURE */
  77. #include <string.h>
  78. #include "rp.h"
  79. #include "boards.h"
  80.  
  81. #ifdef __STORM__
  82.    #pragma chip
  83. #endif
  84.  
  85. MODULE struct Image*  image[FUNCTIONS + 1];
  86. MODULE struct BitMap* bitmap[FUNCTIONS + 1];
  87. MODULE STRPTR         imagename[FUNCTIONS + 1] =
  88. {   "PROGDIR:images/f1.ilbm",
  89.     "PROGDIR:images/f2.ilbm",
  90.     "PROGDIR:images/f3.ilbm",
  91.     "PROGDIR:images/f4.ilbm",
  92.     "PROGDIR:images/f5.ilbm",
  93.     "PROGDIR:images/f6.ilbm",
  94.     "PROGDIR:images/f7.ilbm",
  95.     "PROGDIR:images/f8.ilbm",
  96.     "PROGDIR:images/f9.ilbm",
  97.     "PROGDIR:images/f10.ilbm",
  98.     "PROGDIR:images/amigan.ilbm"
  99. };
  100. MODULE STRPTR FunctionDesc[FUNCTIONS + 2] =
  101. {   // Edit
  102.     "Bug report",         // 1
  103.     "Aminet readme",      // 2
  104.     "Battery-backed RAM", // 9
  105.     // View
  106.     "Manufacturer IDs",   // 5
  107.     "IFF FORMs",          // 6
  108.     // Process
  109.     "Icons",              // 4
  110.     "EOLs/tabs",          // 7
  111.     // Report
  112.     "Path size",          // 8
  113.     "System files",       // 10
  114.     // Conduct
  115.     "ACSE test",          // 3
  116.     // (default)
  117.     TITLEBARTEXT
  118. };
  119.  
  120. #define MENUENTRIES 28
  121. MODULE struct NewMenu NewMenu[MENUENTRIES] =
  122. {   { NM_TITLE, "Project",                  0 , 0,               0, 0},
  123.     {  NM_ITEM, "New",                     "N", NM_ITEMDISABLED, 0, 0},
  124.     {  NM_ITEM, "Open...",                 "O", NM_ITEMDISABLED, 0, 0},
  125.     {  NM_ITEM, NM_BARLABEL,                0 , 0,               0, 0},
  126.     {  NM_ITEM, "Save",                    "S", NM_ITEMDISABLED, 0, 0},
  127.     {  NM_ITEM, "Save As...",              "A", NM_ITEMDISABLED, 0, 0},
  128.     {  NM_ITEM, NM_BARLABEL,                0 , 0,               0, 0},
  129.     {  NM_ITEM, "Quit Report+",            "Q", 0,               0, 0},
  130.     { NM_TITLE, "Tools",                    0,  0,               0, 0},
  131.     {  NM_ITEM, "Main Menu",               "`", 0,               0, 0},
  132.     {  NM_ITEM, NM_BARLABEL,                0 , 0,               0, 0},
  133.     {  NM_ITEM, "Edit Bug Report",         "1", 0,               0, 0},
  134.     {  NM_ITEM, "Edit Aminet Readmet",     "2", 0,               0, 0},
  135.     {  NM_ITEM, "Edit Battery-Backed RAM", "9", 0,               0, 0},
  136.     {  NM_ITEM, NM_BARLABEL,                0 , 0,               0, 0},
  137.     {  NM_ITEM, "View Manufacturer IDs",   "5", 0,               0, 0},
  138.     {  NM_ITEM, "View IFF FORMs",          "6", 0,               0, 0},
  139.     {  NM_ITEM, NM_BARLABEL,                0 , 0,               0, 0},
  140.     {  NM_ITEM, "Process Icons",           "4", 0,               0, 0},
  141.     {  NM_ITEM, "Process EOLs/Tabs",       "7", 0,               0, 0},
  142.     {  NM_ITEM, NM_BARLABEL,                0 , 0,               0, 0},
  143.     {  NM_ITEM, "Report Path Size",        "8", 0,               0, 0},
  144.     {  NM_ITEM, "Report System Files",     "0", 0,               0, 0},
  145.     {  NM_ITEM, NM_BARLABEL,                0 , 0,               0, 0},
  146.     {  NM_ITEM, "Conduct ACSE Test",       "3", 0,               0, 0},
  147.     { NM_TITLE, "Help",                     0 , 0,               0, 0},
  148.     {  NM_ITEM, "About...",                "?", 0,               0, 0},
  149.     {   NM_END, NULL,                       0 , 0,               0, 0}
  150. };
  151.  
  152. MODULE void clearkybd(void);
  153. MODULE void menu(void);
  154. MODULE void parsewb(void);
  155. MODULE void eachwildcard(STRPTR subpattern, ABOOL gui);
  156. MODULE void menu_loop(ULONG gid);
  157. MODULE void sender_loop(ULONG gid);
  158. MODULE void about_loop(void);
  159.  
  160. int CXBRK(void)    { return(0); } /* Disable SAS/C Ctrl-C handling */
  161. int chkabort(void) { return(0); } /* really */
  162.  
  163. MODULE  struct Window*           AboutWindowPtr  = NULL;
  164. AGLOBAL struct Library          *WindowBase      = NULL,
  165.                                 *LayoutBase      = NULL,
  166.                                 *ButtonBase      = NULL,
  167.                                 *TextEditorBase  = NULL,
  168.                                 *LabelBase       = NULL,
  169.                                 *ListBrowserBase = NULL,
  170.                                 *ChooserBase     = NULL,
  171.                                 *StringBase      = NULL,
  172.                                 *CheckBoxBase    = NULL,
  173.                                 *BoardsBase      = NULL,
  174.                                 *BitMapBase      = NULL,
  175.                                 *FuelGaugeBase   = NULL,
  176.                                 *IntegerBase     = NULL,
  177.                                 *RadioButtonBase = NULL,
  178.                                 *SpaceBase       = NULL;
  179. AGLOBAL TEXT                    asldir[PATHNAMEFIELD + 1],
  180.                                 aslresult[PATHNAMEFIELD + 1],
  181.                                 IOBuffer[LONGESTFIELD + 1],
  182.                                 string[LONGESTFIELD + 1],
  183.                                 weekdaystring[LEN_DATSTRING],
  184.                                 datestring[LEN_DATSTRING],
  185.                                 timestring[LEN_DATSTRING],
  186.                                 cpuline[VLONGFIELD + 1];
  187. AGLOBAL WORD                    xsize;
  188. AGLOBAL SBYTE                   page             = 0,
  189.                                 closer           = 0;
  190. AGLOBAL ULONG                   increment,
  191.                                 offset,
  192.                                 wbval,
  193.                                 aboutsignal,
  194.                                 signal;
  195. AGLOBAL ABOOL                   BattBuffer[96],
  196.                                 done             = FALSE,
  197.                                 ram              = FALSE,
  198.                                 stop             = FALSE;
  199. AGLOBAL struct Library*         IconBase         = NULL;
  200. AGLOBAL struct Menu*            MenuPtr          = NULL;
  201. AGLOBAL struct Screen*          ScreenPtr        = NULL;
  202. AGLOBAL struct Window*          MainWindowPtr    = NULL;
  203. AGLOBAL struct TextFont*        FontPtr          = NULL;
  204. AGLOBAL struct VisualInfo*      VisualInfoPtr    = NULL;
  205. AGLOBAL struct ExAllData*       EADataPtr        = NULL;
  206. AGLOBAL struct List             EmptyList,
  207.                                 FileList;
  208. AGLOBAL struct SharedStruct shared =
  209. {   0,
  210.     "", ""
  211. };
  212.  
  213. IMPORT struct ExecBase*     SysBase;
  214. // from f1.c
  215. IMPORT struct ReportStruct  report;
  216. // from f2.c
  217. IMPORT struct AminetStruct  aminet;
  218. // from f3.c
  219. IMPORT ABOOL                acsestop;
  220. // from f4.c
  221. IMPORT struct IconStruct    icon;
  222. IMPORT struct Gadget*       icon_gadgets[GIDS_4 + 1];
  223. IMPORT ABOOL                quit;
  224. // from f6.c
  225. IMPORT struct IFFStruct     iff;
  226. // from f7.c
  227. IMPORT struct Gadget*       eol_gadgets[GIDS_7 + 1];
  228. // from f8.c
  229. IMPORT struct SizeStruct    size;
  230. // from f9.c
  231. IMPORT struct Library*      BattMemBase;
  232. // from f10.c
  233. IMPORT struct FilesStruct   files;
  234.  
  235. AGLOBAL       Object*          WinObject[FUNCTIONS + 1]; // note that WindowObject is a reserved macro
  236. AGLOBAL struct TextAttr        Topaz8 =
  237. {    (STRPTR) "topaz.font", 8, FS_NORMAL, FPF_ROMFONT | FPF_DESIGNED
  238. }; // "topaz.font" is case-sensitive
  239.  
  240. MODULE BPTR                    NilHandle         = NULL;
  241. MODULE TEXT                    pubscreen[256 + 1];
  242. MODULE ABOOL                   logo              = TRUE;
  243. MODULE        Object*          AboutWinObject    = NULL;
  244. MODULE struct Gadget          *gadgets[GIDS_0 + 1],
  245.                               *sender_gadgets[GIDS_S + 1];
  246. MODULE struct RDArgs*          ArgsPtr           = NULL;
  247. MODULE struct WBArg*           WBArg             = NULL;
  248. MODULE struct WBStartup*       WBMsg             = NULL;
  249. MODULE struct ASLBase*         ASLBase           = NULL;
  250. MODULE struct GadToolsBase*    GadToolsBase      = NULL;
  251. MODULE struct IFFParseBase*    IFFParseBase      = NULL;
  252. MODULE struct IntuitionBase*   IntuitionBase     = NULL;
  253. MODULE struct Library*         VersionBase       = NULL;
  254. MODULE struct EasyStruct       EasyStruct =
  255. {   sizeof(struct EasyStruct),
  256.     0,
  257.     "Report+: Error",
  258.     NULL,
  259.     "Quit"
  260. };
  261. MODULE SLONG itemnum[FUNCTIONS + 1] =
  262. {   IN_MAINMENU,
  263.     IN_F1,
  264.     IN_F2,
  265.     IN_F3,
  266.     IN_F4,
  267.     IN_F5,
  268.     IN_F6,
  269.     IN_F7,
  270.     IN_F8,
  271.     IN_F9,
  272.     IN_F10
  273. };
  274.  
  275. /* FUNCTIONS -------------------------------------------------------------- */
  276.  
  277. int main(int argc, char** argv)
  278. {   UWORD  i;
  279.     SLONG  args[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  280.     SLONG  number = 0, hostid /* = 7 */ ;
  281.     BPTR   ConfigHandle /* = NULL */ ,
  282.            OldDir;
  283.  
  284.     /* Start of program.
  285.  
  286.     version embedding into executable */
  287.  
  288.     if (0) /* that is, never */
  289.         Printf("$VER: Report+ 5.65 (15.2.2003)"); /* always d.m.y format */
  290.  
  291.     for (i = 0; i <= FUNCTIONS; i++)
  292.     {   WinObject[i] = NULL;
  293.     }
  294.  
  295.     /* Check for OS3.9+... */
  296.     if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 40L)))
  297.     {   Printf("Report+: Need AmigaOS 3.9+!\n");
  298.         cleanexit(EXIT_FAILURE);
  299.     }
  300.     if (SysBase->LibNode.lib_Version < 40L)
  301.     {   Printf("Report+: Need AmigaOS 3.9+!\n");
  302.         cleanexit(EXIT_FAILURE);
  303.     }
  304.  
  305.     if (!(VersionBase = (struct Library *) OpenLibrary("version.library", 0L)))
  306.         rq("Can't open version.library!");
  307.     wbval = VersionBase->lib_Version;
  308.     CloseLibrary((struct Library *) VersionBase);
  309.     VersionBase = NULL;
  310.     if (wbval < 45)
  311.     {   Printf("Report+: Need AmigaOS 3.9+!\n");
  312.         cleanexit(EXIT_FAILURE);
  313.     }
  314.  
  315.     if (!(GadToolsBase = (struct ASLBase *) OpenLibrary("gadtools.library", 38L)))
  316.         rq("Can't open GadTools.library V38+!");
  317.     if (!(ASLBase = (struct ASLBase *) OpenLibrary("asl.library", 0L)))
  318.         rq("Can't open ASL.library!");
  319.     if (!(IFFParseBase = (struct IFFParseBase *) OpenLibrary("iffparse.library", 0L)))
  320.         rq("Can't open IFFParse.library!");
  321.     // it would be better to disable only the IFF viewer rather than abort
  322.     // the entire program.
  323.     if (!(FontPtr = OpenFont(&Topaz8)))
  324.     {   rq("Can't open Topaz 8 font!");
  325.     }
  326.  
  327.     if (!(ButtonBase      = OpenLibrary("gadgets/button.gadget", 44)))
  328.                        rq("OpenLibrary(\"gadgets/button.gadget\") failed!");
  329.     if (!(CheckBoxBase    = OpenLibrary("gadgets/checkbox.gadget", 44)))
  330.                        rq("OpenLibrary(\"gadgets/checkbox.gadget\") failed!");
  331.     if (!(ChooserBase     = OpenLibrary("gadgets/chooser.gadget", 44)))
  332.                        rq("OpenLibrary(\"gadgets/chooser.gadget\") failed!");
  333.     if (!(LabelBase       = OpenLibrary("images/label.image", 44)))
  334.                        rq("OpenLibrary(\"images/label.image\") failed!");
  335.     if (!(LayoutBase      = OpenLibrary("gadgets/layout.gadget", 44)))
  336.                        rq("OpenLibrary(\"gadgets/layout.gadget\") failed!");
  337.     if (!(ListBrowserBase = OpenLibrary("gadgets/listbrowser.gadget", 0)))
  338.                        rq("OpenLibrary(\"gadgets/listbrowser.gadget\") failed!");
  339.     if (!(StringBase      = OpenLibrary("gadgets/string.gadget", 44)))
  340.                        rq("OpenLibrary(\"gadgets/string.gadget\") failed!");
  341.     if (!(TextEditorBase  = OpenLibrary("gadgets/texteditor.gadget", 0)))
  342.                        rq("OpenLibrary(\"gadgets/texteditor.gadget\") failed!");
  343.     if (!(WindowBase      = OpenLibrary("window.class", 44)))
  344.                        rq("OpenLibrary(\"window.class\") failed!");
  345.     if (!(BitMapBase      = OpenLibrary("images/bitmap.image", 44)))
  346.                        rq("OpenLibrary(\"images/bitmap.image\") failed!");
  347.     if (!(FuelGaugeBase   = OpenLibrary("gadgets/fuelgauge.gadget", 0)))
  348.                        rq("OpenLibrary(\"gadgets/fuelgauge.gadget\") failed!");
  349.     if (!(IntegerBase     = OpenLibrary("gadgets/integer.gadget", 44)))
  350.                        rq("OpenLibrary(\"gadgets/integer.gadget\") failed!");
  351.     if (!(RadioButtonBase = OpenLibrary("gadgets/radiobutton.gadget", 45)))
  352.                        rq("OpenLibrary(\"gadgets/radiobutton.gadget\") (V45) failed!");
  353.     if (!(SpaceBase       = OpenLibrary("gadgets/space.gadget", 44)))
  354.                        rq("OpenLibrary(\"gadgets/space.gadget\") (V44) failed!");
  355.     if (!(IconBase        = OpenLibrary("icon.library", 44)))
  356.                        rq("Need icon.library V44+!");
  357.           BoardsBase      = OpenLibrary("boards.library", 0);
  358.  
  359.     pubscreen[0] = 0;
  360.     NewList(&EmptyList);
  361.     NewList(&FileList);
  362.     for (i = 0; i <= FUNCTIONS; i++)
  363.     {   image[i]  =
  364.         bitmap[i] = NULL;
  365.     }
  366.     if (!(EADataPtr = AllocVec(4096, MEMF_CLEAR | MEMF_PUBLIC)))
  367.     {   rq("Out of memory!");
  368.     }
  369.  
  370.     /* This is done for speed. Even though the Version command *might* be
  371.     resident, or *might* fit entirely into the disk buffers, we shouldn't
  372.     count on this being the case. So we copy the Version command into RAM:. */
  373.  
  374.     NilHandle = Open("NIL:", MODE_NEWFILE);
  375.     if (NilHandle)
  376.     {   if (!SystemTags("C:Copy C:Version RAM: >NIL:", SYS_Output, NilHandle, TAG_DONE))
  377.         {   ram = TRUE;
  378.         }
  379.         if (!SystemTags("C:CPU >T:ReportPlus.temp", SYS_Output, NilHandle, TAG_DONE))
  380.         {   readordie("T:ReportPlus.temp");
  381.             DeleteFile("T:ReportPlus.temp"); /* returns FALSE for failure */
  382.  
  383.             for (i = 0; i <= VLONGFIELD; i++)
  384.             {   if (IOBuffer[i] == LF)
  385.                 {   IOBuffer[i] = 0;
  386.                     break;
  387.             }   }
  388.             strcpy(cpuline, IOBuffer);
  389.         } else
  390.         {   strcpy(cpuline, "?");
  391.         }
  392.         Close(NilHandle);
  393.         NilHandle = NULL;
  394.     } else
  395.     {   strcpy(cpuline, "?");
  396.     }
  397.  
  398.     report_init();     // f1  list init, var init
  399.     aminet_init();     // f2  list init: memory loss?
  400.     iff_init();        // f6  var init
  401.     size_init();       // f8  list init
  402.     files_init();      // f10  pen init, list init
  403.     /* those must be done before we handle CLI arguments */
  404.  
  405.     if (argc) /* started from CLI */
  406.     {   if (!(ArgsPtr = ReadArgs
  407.         (   "PUBSCREEN/K,-N=NOLOGO/S,FUNCTION/N,-I=ICONTYPE/K,"
  408.             "RESET/S,TIMEOUT/S,LUNS/S,SYNC_XFER/S,SLOW_SYNC/S,TAG_QUEUES/S,HOST_ID/K/N,"
  409.             "FILE/F",
  410.             (LONG *) args,
  411.             NULL
  412.     )))
  413.         {   Printf
  414.             (   "Usage: %s [PUBSCREEN <screen>] [-n|NOLOGO] "
  415.                 "[[FUNCTION] <function>] "
  416.                 "[-i|ICONTYPE DISK|DRAWER|TOOL|PROJECT|TRASHCAN|DEVICE|KICKSTART|APPICON] "
  417.                 "[RESET [TIMEOUT] [LUNS] [SYNC_XFER] [SLOW_SYNC] [TAG_QUEUES] [HOST_ID <host_id>]] "
  418.                 "[[FILE] <file(s)...>]]\n",
  419.                 argv[0]
  420.             );
  421.             cleanexit(EXIT_FAILURE);
  422.     }
  423.         if (args[0])
  424.         {   strcpy(pubscreen, (STRPTR) args[0]);
  425.         }
  426.         if (args[1])
  427.         {   logo = FALSE;
  428.         }
  429.         if (args[2])
  430.         {   number = (SLONG) (*((SLONG *) args[2]));
  431.             if (number >= 1 && number <= FUNCTIONS)
  432.             {   page = closer = (number * 10) + 1;
  433.                 shared.function = number;
  434.             } else
  435.             {   Printf("Report+: <function> must be 1-%ld!\n", FUNCTIONS);
  436.                 cleanexit(EXIT_FAILURE);
  437.         }   }
  438.         if (args[3])
  439.         {   if (number != 4)
  440.             {   Printf("%s: <function> must be 4 for this!\n", argv[0]);
  441.                 cleanexit(EXIT_FAILURE);
  442.             }
  443.             if (!stricmp((STRPTR) args[3], "DISK"))
  444.             {   icon.type = WBDISK;
  445.             } elif (!stricmp((STRPTR) args[3], "DRAWER"))
  446.             {   icon.type = WBDRAWER;
  447.             } elif (!stricmp((STRPTR) args[3], "TOOL"))
  448.             {   icon.type = WBTOOL;
  449.             } elif (!stricmp((STRPTR) args[3], "PROJECT"))
  450.             {   icon.type = WBPROJECT;
  451.             } elif (!stricmp((STRPTR) args[3], "TRASHCAN"))
  452.             {   icon.type = WBGARBAGE;
  453.             } elif (!stricmp((STRPTR) args[3], "DEVICE"))
  454.             {   icon.type = WBDEVICE;
  455.             } elif (!stricmp((STRPTR) args[3], "KICKSTART"))
  456.             {   icon.type = WBKICK;
  457.             } elif (!stricmp((STRPTR) args[3], "APPICON"))
  458.             {   icon.type = WBAPPICON;
  459.             } else
  460.             {   Printf("%s: <icontype> must be DISK, DRAWER, TOOL, PROJECT, TRASHCAN, DEVICE, KICKSTART or APPICON!\n", argv[0]);
  461.                 cleanexit(EXIT_FAILURE);
  462.         }   }
  463.         if (args[4] || args[5] || args[6] || args[7] || args[8] || args[9] || args[10])
  464.         {   if (number != 9)
  465.             {   Printf("%s: <function> must be 9 for this!\n", argv[0]);
  466.                 cleanexit(EXIT_FAILURE);
  467.             }
  468.             if (!args[4])
  469.             {   Printf("%s: You need the RESET switch for this!\n", argv[0]);
  470.                 cleanexit(EXIT_FAILURE);
  471.             }
  472.             for (i = 0; i <= 95; i++)
  473.             {   BattBuffer[i] = FALSE;
  474.             }
  475.             BattBuffer[BATTMEM_AMIGA_AMNESIA_ADDR]          =
  476.             BattBuffer[BATTMEM_SHARED_AMNESIA_ADDR]         = TRUE; // these bits are inverted
  477.             if (args[5])
  478.             {   BattBuffer[BATTMEM_SCSI_TIMEOUT_ADDR]       = TRUE;
  479.             } else BattBuffer[BATTMEM_SCSI_TIMEOUT_ADDR]    = FALSE;
  480.             if (args[6])
  481.             {   BattBuffer[BATTMEM_SCSI_LUNS_ADDR]          = TRUE;
  482.             } else BattBuffer[BATTMEM_SCSI_LUNS_ADDR]       = FALSE;
  483.             if (args[7])
  484.             {   BattBuffer[BATTMEM_SCSI_SYNC_XFER_ADDR]     = TRUE;
  485.             } else BattBuffer[BATTMEM_SCSI_SYNC_XFER_ADDR]  = FALSE;
  486.             if (args[8])
  487.             {   BattBuffer[BATTMEM_SCSI_FAST_SYNC_ADDR]     = TRUE;
  488.             } else BattBuffer[BATTMEM_SCSI_FAST_SYNC_ADDR]  = FALSE;
  489.             if (args[9])
  490.             {   BattBuffer[BATTMEM_SCSI_TAG_QUEUES_ADDR]    = TRUE;
  491.             } else BattBuffer[BATTMEM_SCSI_TAG_QUEUES_ADDR] = FALSE;
  492.             if (args[10]) // these bits are inverted
  493.             {   hostid = (SLONG) (*((SLONG *) args[10]));
  494.                 if (hostid < 0 || hostid > 7)
  495.                 {   Printf("%s: <host_id> must be 0-7!\n", argv[0]);
  496.                     cleanexit(EXIT_FAILURE);
  497.                 }
  498.                 BattBuffer[BATTMEM_SCSI_HOST_ID_ADDR]     = (hostid & 4)? 0 : 1;
  499.                 BattBuffer[BATTMEM_SCSI_HOST_ID_ADDR + 1] = (hostid & 2)? 0 : 1;
  500.                 BattBuffer[BATTMEM_SCSI_HOST_ID_ADDR + 2] = (hostid & 1)? 0 : 1;
  501.             }
  502.             if (!BattMemBase)
  503.             {   if (!(BattMemBase = OpenResource(BATTMEMNAME)))
  504.                 {   rq("Can't open battery RAM resource!");
  505.             }   }
  506.             writebatt(FALSE);
  507.             Printf("Done.\n");
  508.             cleanexit(EXIT_SUCCESS);
  509.         }
  510.         if (args[11])
  511.         {   switch(number)
  512.             {
  513.             case 1:
  514.                 strcpy(report.output, (STRPTR) args[11]);
  515.                 loadreport();
  516.             break;
  517.             case 2:
  518.                 strcpy(aminet.output, (STRPTR) args[11]);
  519.                 loadaminet();
  520.             break;
  521.             case 4:
  522.                 strcpy(shared.pathname, (STRPTR) args[11]);
  523.                 if (convert(FALSE))
  524.                 {   Printf("All done.\n");
  525.                 } else
  526.                 {   Printf("No matches!\n");
  527.                 }
  528.                 cleanexit(EXIT_SUCCESS);
  529.             break;
  530.             case 6:
  531.                 strcpy(iff.pathname, (STRPTR) args[11]);
  532.             break;
  533.             case 7:
  534.                 strcpy(shared.pathname, (STRPTR) args[11]);
  535.                 if (convert(FALSE))
  536.                 {   Printf("All done.\n");
  537.                 } else
  538.                 {   Printf("No matches!\n");
  539.                 }
  540.                 cleanexit(EXIT_SUCCESS);
  541.             break;
  542.             case 8:
  543.                 strcpy(size.path, (STRPTR) args[11]);
  544.             break;
  545.             case 10:
  546.                 strcpy(files.basepath, (STRPTR) args[11]);
  547.             break;
  548.             default:
  549.                 Printf("Report+: <function> must be 1-2, 4, 6-8, or 10 for this!\n");
  550.                 cleanexit(EXIT_FAILURE);
  551.             break;
  552.     }   }   }
  553.     else /* started from WB */
  554.     {   WBMsg = (struct WBStartup *) argv;
  555.         WBArg = WBMsg->sm_ArgList; /* head of the arg list */
  556.         for (i = 0; i < WBMsg->sm_NumArgs; i++, WBArg++)
  557.         {   if (WBArg->wa_Lock)
  558.             {   /* something that does not support locks */
  559.                 parsewb();
  560.             } else
  561.             {   /* lock supported; change to the proper directory */
  562.                 OldDir = CurrentDir(WBArg->wa_Lock);
  563.                 parsewb();
  564.                 CurrentDir(OldDir);
  565.             }
  566.             if (i == 1)
  567.             {   ; /* we were started from a project icon, which is
  568.                 currently unsupported */
  569.     }   }   }
  570.  
  571.     strcpy(asldir, "PROGDIR:");
  572.     /* RKM Libraries, p. 59-61: */
  573.     lockscreen();
  574.     if (GetVPModeID(&(ScreenPtr->ViewPort)) == INVALID_ID)
  575.     {   rq("Invalid default public screen mode ID!");
  576.     }
  577.     xsize   = ScreenPtr->Width;
  578.     if (!(VisualInfoPtr = (struct VisualInfo *) GetVisualInfo(ScreenPtr, TAG_DONE)))
  579.     {   rq("Can't get GadTools visual info!");
  580.     }
  581.     unlockscreen();
  582.  
  583.     if (!(MenuPtr = (struct Menu *) CreateMenus(NewMenu, TAG_DONE)))
  584.     {   rq("Can't create menus!");
  585.     }
  586.     if (!(LayoutMenus(MenuPtr, VisualInfoPtr, GTMN_NewLookMenus, TRUE, TAG_DONE)))
  587.     {   rq("Can't lay out menus!");
  588.     }
  589.  
  590.     if (ConfigHandle = (BPTR) Open("PROGDIR:ReportPlus.config", MODE_OLDFILE))
  591.     {   if (Read(ConfigHandle, IOBuffer, 25) != -1)
  592.         {   manuf_config(); //                                         20
  593.             icon_config();  //                                 161718
  594.             iff_config();   //                                       19
  595.             eol_config();   //   0102030405
  596.             size_config();  // 00          06                15          2122  24
  597.             files_config(); //               0708091011121314                23
  598.         }
  599.         Close(ConfigHandle);
  600.         // ConfigHandle = NULL;
  601.     }
  602.  
  603.     while(1)
  604.     {   if (page != 1)
  605.         {   shared.function = page / 10;
  606.         }
  607.         if (page == 1)
  608.             sender();
  609.         elif (page == 11)
  610.             report1();
  611.         elif (page == 12)
  612.             report2();
  613.         elif (page == 21)
  614.             aminet1();
  615.         elif (page == 31)
  616.             acse1();
  617.         elif (page == 32)
  618.             acse2();
  619.         elif (page == 41)
  620.             icon1();
  621.         elif (page == 51)
  622.             manuf1();
  623.         elif (page == 61)
  624.             iff1();
  625.         elif (page == 71)
  626.             eol1();
  627.         elif (page == 81)
  628.             size1();
  629.         elif (page == 91)
  630.             batt1();
  631.         elif (page == 101)
  632.             files1();
  633.         else
  634.         {   /* assert(page == 0); */
  635.             menu();
  636. }   }   }
  637.  
  638. MODULE void menu(void)
  639. {   PERSIST ABOOL       first = TRUE;
  640.     AUTO    struct Hook Hook0Struct;
  641.     AUTO    ULONG       i, tag[2];
  642.     AUTO    LONG        bgpen;
  643.  
  644.     /* Each of these calls to NewObject() loses 32 bytes, for a loss of
  645.        388 bytes. */
  646.  
  647.     if (first)
  648.     {   lockscreen();
  649.         for (i = 0; i < FUNCTIONS; i++)
  650.         {   if (!(image[i] = NewObject
  651.             (   BITMAP_GetClass(), NULL,
  652.                 BITMAP_SourceFile, imagename[i],
  653.                 BITMAP_Width,      35,
  654.                 BITMAP_Height,     32,
  655.                 BITMAP_Screen,     ScreenPtr,
  656.             TAG_END)
  657.             ))
  658.             {   rq("Can't create ReAction image(s)!");
  659.             }
  660.             GetAttr(BITMAP_BitMap, image[i], (ULONG *) &bitmap[i]);
  661.         }
  662.         unlockscreen();
  663.         first = FALSE;
  664.     }
  665.  
  666.     /* PAGE 0 ************************************************************* */
  667.  
  668.     InitHook(&Hook0Struct, Hook0Func, NULL);
  669.  
  670.     lockscreen();
  671.  
  672.     bgpen = FindColor
  673.     (   ScreenPtr->ViewPort.ColorMap,
  674.         0x96969696,
  675.         0x96969696,
  676.         0x96969696,
  677.         -1
  678.     );
  679.  
  680.     if (logo)
  681.     {   tag[0] = LAYOUT_AddImage;
  682.         tag[1] = NewObject
  683.         (   BITMAP_GetClass(), NULL,
  684.             // bitmap tags
  685.             BITMAP_SourceFile, "PROGDIR:images/logo.ilbm",
  686.             BITMAP_Masking,    TRUE,
  687.             BITMAP_Screen,     ScreenPtr,
  688.             TAG_DONE
  689.         );
  690.     } else
  691.     {   tag[0] = TAG_IGNORE;
  692.         tag[1] = NULL;
  693.     }
  694.  
  695.     if (!(WinObject[0] = NewObject(WINDOW_GetClass(), NULL,
  696.         // window tags
  697.         WA_PubScreen,             ScreenPtr,
  698.         WA_ScreenTitle,           TITLEBARTEXT,
  699.         WA_Title,                 "Report+: Main Menu",
  700.         WA_Activate,              TRUE,
  701.         WA_DepthGadget,           TRUE,
  702.         WA_DragBar,               TRUE,
  703.         WA_CloseGadget,           TRUE,
  704.         WA_IDCMP,                 IDCMP_RAWKEY | IDCMP_INTUITICKS,
  705.         WINDOW_IDCMPHook,         &Hook0Struct,
  706.         WINDOW_IDCMPHookBits,     IDCMP_RAWKEY | IDCMP_INTUITICKS,
  707.         WINDOW_MenuStrip,         MenuPtr,
  708.         WINDOW_Position,          WPOS_CENTERSCREEN,
  709.         WINDOW_ParentGroup,       gadgets[GID_0_LY1] =
  710.         NewObject
  711.         (   LAYOUT_GetClass(),         NULL,
  712.             // root-layout tags
  713.             LAYOUT_Orientation,        LAYOUT_ORIENT_VERT,
  714.             LAYOUT_SpaceOuter,         TRUE,
  715.             LAYOUT_DeferLayout,        TRUE,
  716.             LAYOUT_AddChild,
  717.             NewObject
  718.             (   LAYOUT_GetClass(),     NULL,
  719.                 // layout tags
  720.                 LAYOUT_Orientation,    LAYOUT_ORIENT_HORIZ,
  721.                 LAYOUT_DeferLayout,    TRUE,
  722.                 LAYOUT_HorizAlignment, LALIGN_CENTER,
  723.                 tag[0],                tag[1],
  724.                 TAG_DONE
  725.             ),
  726.             LAYOUT_AddChild,
  727.             NewObject
  728.             (   LAYOUT_GetClass(), NULL,
  729.                 // layout tags
  730.                 LAYOUT_Orientation,    LAYOUT_ORIENT_HORIZ,
  731.                 LAYOUT_DeferLayout,    TRUE,
  732.                 LAYOUT_HorizAlignment, LALIGN_CENTER,
  733.                 LAYOUT_AddImage,
  734.                 NewObject
  735.                 (   LABEL_GetClass(),    NULL,
  736.                     // label tags
  737.                     LABEL_Justification, LJ_CENTRE,
  738.                     LABEL_Text,          "Edit:",
  739.                     TAG_END
  740.                 ),
  741.                 TAG_END
  742.             ),
  743.             CHILD_WeightedHeight,      0,
  744.             LAYOUT_AddChild,
  745.             NewObject
  746.             (   LAYOUT_GetClass(),         NULL,
  747.                 // layout tags
  748.                 LAYOUT_Orientation,        LAYOUT_ORIENT_HORIZ,
  749.                 LAYOUT_DeferLayout,        TRUE,
  750.                 LAYOUT_AddChild,           gadgets[GID_0_BU1] =
  751.                 NewObject
  752.                 (   NULL, "button.gadget",
  753.                     // button tags
  754.                     GA_ID,                 GID_0_BU1,
  755.                     GA_Left,               20,
  756.                     GA_Top,                20,
  757.                     GA_Width,              41,
  758.                     GA_Height,             40,
  759.                     GA_RelVerify,          TRUE,
  760.                     GA_Image,
  761.                     NewObject
  762.                     (   BITMAP_GetClass(),   NULL,
  763.                         // bitmap tags
  764.                         BITMAP_BitMap,       bitmap[1 - 1],
  765.                         BITMAP_Width,        35,
  766.                         BITMAP_Height,       32,
  767.                         TAG_DONE
  768.                     ),
  769.                     BUTTON_BackgroundPen,    bgpen,
  770.                     BUTTON_FillPen,          bgpen,
  771.                     TAG_DONE
  772.                 ),
  773.                 LAYOUT_AddChild,           gadgets[GID_0_BU2] =
  774.                 NewObject
  775.                 (   NULL, "button.gadget",
  776.                     // button tags
  777.                     GA_ID,                 GID_0_BU2,
  778.                     GA_Left,               20,
  779.                     GA_Top,                20,
  780.                     GA_Width,              41,
  781.                     GA_Height,             40,
  782.                     GA_RelVerify,          TRUE,
  783.                     GA_Image,
  784.                     NewObject
  785.                     (   BITMAP_GetClass(),   NULL,
  786.                         // bitmap tags
  787.                         BITMAP_BitMap,       bitmap[2 - 1],
  788.                         BITMAP_Width,        35,
  789.                         BITMAP_Height,       32,
  790.                         TAG_DONE
  791.                     ),
  792.                     BUTTON_BackgroundPen,    bgpen,
  793.                     BUTTON_FillPen,          bgpen,
  794.                     TAG_DONE
  795.                 ),
  796.                 LAYOUT_AddChild,           gadgets[GID_0_BU3] =
  797.                 NewObject
  798.                 (   NULL,                  "button.gadget",
  799.                     GA_ID,                 GID_0_BU3,
  800.                     GA_Left,               20,
  801.                     GA_Top,                20,
  802.                     GA_Width,              41,
  803.                     GA_Height,             40,
  804.                     GA_RelVerify,          TRUE,
  805.                     GA_Image,              NewObject
  806.                     (   BITMAP_GetClass(),   NULL,
  807.                         // bitmap tags
  808.                         BITMAP_BitMap,       bitmap[9 - 1],
  809.                         BITMAP_Width,        35,
  810.                         BITMAP_Height,       32,
  811.                         TAG_DONE
  812.                     ),
  813.                     BUTTON_BackgroundPen,    bgpen,
  814.                     BUTTON_FillPen,          bgpen,
  815.                 TAG_END),
  816.             TAG_END),
  817.             LAYOUT_AddChild,
  818.             NewObject
  819.             (   LAYOUT_GetClass(),         NULL,
  820.                 // layout tags
  821.                 LAYOUT_Orientation,        LAYOUT_ORIENT_HORIZ,
  822.                 LAYOUT_DeferLayout,        TRUE,
  823.                 LAYOUT_AddChild,
  824.                 NewObject
  825.                 (   LAYOUT_GetClass(),         NULL,
  826.                     // layout tags
  827.                     LAYOUT_Orientation,        LAYOUT_ORIENT_VERT,
  828.                     LAYOUT_DeferLayout,        TRUE,
  829.                     LAYOUT_AddChild,
  830.                     NewObject
  831.                     (    LAYOUT_GetClass(),    NULL,
  832.                          // layout tags
  833.                          LAYOUT_Orientation,   LAYOUT_ORIENT_HORIZ,
  834.                          LAYOUT_DeferLayout,   TRUE,
  835.                          LAYOUT_HorizAlignment, LALIGN_CENTER,
  836.                          LAYOUT_AddImage,
  837.                          NewObject
  838.                          (   LABEL_GetClass(), NULL,
  839.                              // label tags
  840.                              LABEL_Justification, LJ_CENTRE,
  841.                              LABEL_Text,          "View:",
  842.                              TAG_END
  843.                          ),
  844.                          TAG_DONE
  845.                     ),
  846.                     LAYOUT_AddChild,
  847.                     NewObject
  848.                     (   LAYOUT_GetClass(),         NULL,
  849.                         // layout tags
  850.                         LAYOUT_Orientation,        LAYOUT_ORIENT_HORIZ,
  851.                         LAYOUT_DeferLayout,        TRUE,
  852.                         LAYOUT_AddChild,           gadgets[GID_0_BU4] =
  853.                         NewObject
  854.                         (   NULL,                  "button.gadget",
  855.                             GA_ID,                 GID_0_BU4,
  856.                             GA_Left,               20,
  857.                             GA_Top,                20,
  858.                             GA_Width,              41,
  859.                             GA_Height,             40,
  860.                             GA_RelVerify,          TRUE,
  861.                             GA_Image,              NewObject
  862.                             (   BITMAP_GetClass(),   NULL,
  863.                                 // bitmap tags
  864.                                 BITMAP_BitMap,       bitmap[5 - 1],
  865.                                 BITMAP_Width,        35,
  866.                                 BITMAP_Height,       32,
  867.                                 TAG_DONE
  868.                             ),
  869.                             BUTTON_BackgroundPen,    bgpen,
  870.                             BUTTON_FillPen,          bgpen,
  871.                             TAG_DONE
  872.                         ),
  873.                         LAYOUT_AddChild,           gadgets[GID_0_BU5] =
  874.                         NewObject
  875.                         (   NULL, "button.gadget",
  876.                             // button tags
  877.                             GA_ID,                 GID_0_BU5,
  878.                             GA_Left,               20,
  879.                             GA_Top,                20,
  880.                             GA_Width,              41,
  881.                             GA_Height,             40,
  882.                             GA_RelVerify,          TRUE,
  883.                             GA_Image,              NewObject
  884.                             (   BITMAP_GetClass(),   NULL,
  885.                                 // bitmap tags
  886.                                 BITMAP_BitMap,       bitmap[6 - 1],
  887.                                 BITMAP_Width,        35,
  888.                                 BITMAP_Height,       32,
  889.                                 TAG_DONE
  890.                             ),
  891.                             BUTTON_BackgroundPen,    bgpen,
  892.                             BUTTON_FillPen,          bgpen,
  893.                             TAG_DONE
  894.                         ),
  895.                         TAG_DONE
  896.                     ),
  897.                     TAG_DONE
  898.                 ),
  899.                 LAYOUT_AddChild,
  900.                 NewObject
  901.                 (   LAYOUT_GetClass(),         NULL,
  902.                     // layout tags
  903.                     LAYOUT_Orientation,        LAYOUT_ORIENT_VERT,
  904.                     LAYOUT_DeferLayout,        TRUE,
  905.                     LAYOUT_AddChild,
  906.                     NewObject
  907.                     (    LAYOUT_GetClass(),    NULL,
  908.                          // layout tags
  909.                          LAYOUT_Orientation,   LAYOUT_ORIENT_HORIZ,
  910.                          LAYOUT_DeferLayout,   TRUE,
  911.                          LAYOUT_HorizAlignment, LALIGN_CENTER,
  912.                          LAYOUT_AddImage,
  913.                          NewObject
  914.                          (   LABEL_GetClass(), NULL,
  915.                              // label tags
  916.                              LABEL_Justification, LJ_CENTRE,
  917.                              LABEL_Text,          "Process:",
  918.                          TAG_END),
  919.                     TAG_END),
  920.                     CHILD_WeightedHeight,      0,
  921.                     LAYOUT_AddChild,
  922.                     NewObject
  923.                     (   LAYOUT_GetClass(),         NULL,
  924.                         LAYOUT_Orientation,        LAYOUT_ORIENT_HORIZ,
  925.                         LAYOUT_DeferLayout,        TRUE,
  926.                         LAYOUT_HorizAlignment,     LALIGN_CENTER,
  927.                         LAYOUT_AddChild,           gadgets[GID_0_BU6] =
  928.                         NewObject
  929.                         (   NULL, "button.gadget",
  930.                             // button tags
  931.                             GA_ID,                 GID_0_BU6,
  932.                             GA_Left,               20,
  933.                             GA_Top,                20,
  934.                             GA_Width,              41,
  935.                             GA_Height,             40,
  936.                             GA_RelVerify,          TRUE,
  937.                             GA_Image,              NewObject
  938.                             (   BITMAP_GetClass(),   NULL,
  939.                                 BITMAP_BitMap,       bitmap[4 - 1],
  940.                                 BITMAP_Width,        35,
  941.                                 BITMAP_Height,       32,
  942.                                 TAG_DONE
  943.                             ),
  944.                             BUTTON_BackgroundPen,    bgpen,
  945.                             BUTTON_FillPen,          bgpen,
  946.                         TAG_DONE),
  947.                         LAYOUT_AddChild,           gadgets[GID_0_BU7] =
  948.                         NewObject
  949.                         (   NULL, "button.gadget",
  950.                             // button tags
  951.                             GA_ID,                 GID_0_BU7,
  952.                             GA_Left,               20,
  953.                             GA_Top,                20,
  954.                             GA_Width,              41,
  955.                             GA_Height,             40,
  956.                             GA_RelVerify,          TRUE,
  957.                             GA_Image,              NewObject
  958.                             (   BITMAP_GetClass(),   NULL,
  959.                                 // bitmap tags
  960.                                 BITMAP_BitMap,       bitmap[7 - 1],
  961.                                 BITMAP_Width,        35,
  962.                                 BITMAP_Height,       32,
  963.                                 TAG_DONE
  964.                             ),
  965.                             BUTTON_BackgroundPen,    bgpen,
  966.                             BUTTON_FillPen,          bgpen,
  967.                         TAG_DONE),
  968.                     TAG_DONE),
  969.                 TAG_DONE),
  970.             TAG_DONE),
  971.             LAYOUT_AddChild,
  972.             NewObject
  973.             (   LAYOUT_GetClass(),         NULL,
  974.                 // layout tags
  975.                 LAYOUT_Orientation,        LAYOUT_ORIENT_HORIZ,
  976.                 LAYOUT_DeferLayout,        TRUE,
  977.                 LAYOUT_AddChild,
  978.                 NewObject
  979.                 (   LAYOUT_GetClass(),         NULL,
  980.                     // layout tags
  981.                     LAYOUT_Orientation,        LAYOUT_ORIENT_VERT,
  982.                     LAYOUT_DeferLayout,        TRUE,
  983.                     LAYOUT_AddChild,
  984.                     NewObject
  985.                     (    LAYOUT_GetClass(),       NULL,
  986.                          // layout tags
  987.                          LAYOUT_Orientation,      LAYOUT_ORIENT_HORIZ,
  988.                          LAYOUT_DeferLayout,      TRUE,
  989.                          LAYOUT_HorizAlignment,   LALIGN_CENTER,
  990.                          LAYOUT_AddImage,
  991.                          NewObject
  992.                          (   LABEL_GetClass(),    NULL,
  993.                              // label tags
  994.                              LABEL_Justification, LJ_CENTRE,
  995.                              LABEL_Text,          "Report:",
  996.                              TAG_END
  997.                          ),
  998.                          TAG_DONE
  999.                     ),
  1000.                     LAYOUT_AddChild,
  1001.                     NewObject
  1002.                     (   LAYOUT_GetClass(),         NULL,
  1003.                         // layout tags
  1004.                         LAYOUT_Orientation,        LAYOUT_ORIENT_HORIZ,
  1005.                         LAYOUT_DeferLayout,        TRUE,
  1006.                         LAYOUT_AddChild,           gadgets[GID_0_BU8] =
  1007.                         NewObject
  1008.                         (   NULL, "button.gadget",
  1009.                             // button tags
  1010.                             GA_ID,                 GID_0_BU8,
  1011.                             GA_Left,               20,
  1012.                             GA_Top,                20,
  1013.                             GA_Width,              41,
  1014.                             GA_Height,             40,
  1015.                             GA_RelVerify,          TRUE,
  1016.                             GA_Image,              NewObject
  1017.                             (   BITMAP_GetClass(),   NULL,
  1018.                                 // bitmap tags
  1019.                                 BITMAP_BitMap,       bitmap[8 - 1],
  1020.                                 BITMAP_Width,        35,
  1021.                                 BITMAP_Height,       32,
  1022.                                 TAG_DONE
  1023.                             ),
  1024.                             BUTTON_BackgroundPen,    bgpen,
  1025.                             BUTTON_FillPen,          bgpen,
  1026.                             TAG_DONE
  1027.                         ),
  1028.                         LAYOUT_AddChild,           gadgets[GID_0_BU9] =
  1029.                         NewObject
  1030.                         (   NULL,                  "button.gadget",
  1031.                             // button tags
  1032.                             GA_ID,                 GID_0_BU9,
  1033.                             GA_Left,               20,
  1034.                             GA_Top,                20,
  1035.                             GA_Width,              41,
  1036.                             GA_Height,             40,
  1037.                             GA_RelVerify,          TRUE,
  1038.                             GA_Image,              NewObject
  1039.                             (   BITMAP_GetClass(),   NULL,
  1040.                                 // bitmap tags
  1041.                                 BITMAP_BitMap,       bitmap[10 - 1],
  1042.                                 BITMAP_Width,        35,
  1043.                                 BITMAP_Height,       32,
  1044.                                 TAG_DONE
  1045.                             ),
  1046.                             BUTTON_BackgroundPen,    bgpen,
  1047.                             BUTTON_FillPen,          bgpen,
  1048.                             TAG_DONE
  1049.                         ),
  1050.                         TAG_DONE
  1051.                     ),
  1052.                     TAG_DONE
  1053.                 ),
  1054.                 LAYOUT_AddChild,
  1055.                 NewObject
  1056.                 (   LAYOUT_GetClass(),         NULL,
  1057.                     // layout tags
  1058.                     LAYOUT_Orientation,        LAYOUT_ORIENT_VERT,
  1059.                     LAYOUT_DeferLayout,        TRUE,
  1060.                     LAYOUT_AddChild,
  1061.                     NewObject
  1062.                     (    LAYOUT_GetClass(),    NULL,
  1063.                          // layout tags
  1064.                          LAYOUT_Orientation,   LAYOUT_ORIENT_HORIZ,
  1065.                          LAYOUT_DeferLayout,   TRUE,
  1066.                          LAYOUT_HorizAlignment, LALIGN_CENTER,
  1067.                          LAYOUT_AddImage,
  1068.                          NewObject
  1069.                          (   LABEL_GetClass(), NULL,
  1070.                              // label tags
  1071.                              LABEL_Justification, LJ_CENTRE,
  1072.                              LABEL_Text,          "Conduct:",
  1073.                              TAG_END
  1074.                          ),
  1075.                          TAG_DONE
  1076.                     ),
  1077.                     LAYOUT_AddChild,
  1078.                     NewObject
  1079.                     (   LAYOUT_GetClass(),         NULL,
  1080.                         // layout tags
  1081.                         LAYOUT_Orientation,        LAYOUT_ORIENT_HORIZ,
  1082.                         LAYOUT_DeferLayout,        TRUE,
  1083.                         LAYOUT_AddChild,           gadgets[GID_0_BU10] =
  1084.                         NewObject
  1085.                         (   NULL, "button.gadget",
  1086.                             // button tags
  1087.                             GA_ID,                 GID_0_BU10,
  1088.                             GA_Left,               20,
  1089.                             GA_Top,                20,
  1090.                             GA_Width,              41,
  1091.                             GA_Height,             40,
  1092.                             GA_RelVerify,          TRUE,
  1093.                             GA_Image,              NewObject
  1094.                             (   BITMAP_GetClass(),   NULL,
  1095.                                 // bitmap tags
  1096.                                 BITMAP_BitMap,       bitmap[3 - 1],
  1097.                                 BITMAP_Width,        35,
  1098.                                 BITMAP_Height,       32,
  1099.                                 TAG_DONE
  1100.                             ),
  1101.                             BUTTON_BackgroundPen,  bgpen,
  1102.                             BUTTON_FillPen,        bgpen,
  1103.                             TAG_DONE
  1104.                         ),
  1105.                         TAG_DONE
  1106.                     ),
  1107.                     TAG_DONE
  1108.                 ),
  1109.                 TAG_DONE
  1110.             ),
  1111.             LAYOUT_AddChild,          gadgets[GID_0_ST1] =
  1112.             NewObject
  1113.             (   STRING_GetClass(),    NULL,
  1114.                 // string tags
  1115.                 GA_ID,                GID_0_ST1,
  1116.                 GA_ReadOnly,          TRUE,
  1117.                 STRINGA_TextVal,      TITLEBARTEXT,
  1118.                 TAG_END
  1119.             ),
  1120.             CHILD_WeightedHeight,     0,
  1121.             TAG_DONE
  1122.         ),
  1123.         TAG_DONE
  1124.     )))
  1125.     {   rq("Can't create ReAction gadgets!");
  1126.     }
  1127.     unlockscreen();
  1128.     openwindow();
  1129.     loop();
  1130.     closewindow();
  1131. }
  1132.  
  1133. AGLOBAL void cleanexit(SBYTE rc)
  1134. {   BPTR  ConfigHandle;
  1135.     ULONG i;
  1136.  
  1137.     /* The Amiga loses 24 bytes each time ReportPlus is run...
  1138.  
  1139.     ASL requesters are assumed to be already closed. */
  1140.  
  1141.     /* help|about... */
  1142.     if (AboutWindowPtr)
  1143.     {   DisposeObject(AboutWinObject);
  1144.         AboutWindowPtr = AboutWinObject = NULL;
  1145.     }
  1146.  
  1147.     /* all */
  1148.     unlockscreen(); // in case the screen is locked
  1149.     closewindow();
  1150.  
  1151.     if (MenuPtr)
  1152.     {   FreeMenus(MenuPtr);
  1153.         MenuPtr = NULL;
  1154.     }
  1155.     if (VisualInfoPtr)
  1156.     {   FreeVisualInfo(VisualInfoPtr);
  1157.         VisualInfoPtr = NULL;
  1158.     }
  1159.  
  1160.     /* You can't fool around with attached lists, so we close the window
  1161.     before calling these next routines. */
  1162.  
  1163.     report_die();  // f1  clear list
  1164.     aminet_die();  // f2  clear lists
  1165.     acse_exit();   // f3  close timer
  1166.     icon_die();    // f4  config data
  1167.     manuf_die();   // f5  config data
  1168.     iff_exit();    // f6  free memory, clear lists, close iffhandles
  1169.     iff_die();     // f6  config data
  1170.     eol_die();     // f7  config data
  1171.     size_exit();   // f8  close filehandles/locks, clear full lists
  1172.     size_die();    // f8  clear empty lists
  1173.     files_exit();  // f10 clear full list, close filehandle
  1174.     files_die();   // f10 clear empty list, config data
  1175.  
  1176.     if (NilHandle)
  1177.     {   Close(NilHandle);
  1178.         NilHandle = NULL;
  1179.     }
  1180.     if (ram && (NilHandle = Open("NIL:", MODE_NEWFILE)))
  1181.     {   if (!SystemTags("Delete RAM:Version", SYS_Output, NilHandle, TAG_DONE))
  1182.         {   ram = FALSE;
  1183.         }
  1184.         Close(NilHandle);
  1185.         NilHandle = NULL;
  1186.     }
  1187.  
  1188.     if (EADataPtr)
  1189.     {   FreeVec(EADataPtr);
  1190.         EADataPtr = NULL;
  1191.     }
  1192.     if (FontPtr)
  1193.     {   CloseFont(FontPtr);
  1194.         FontPtr = NULL;
  1195.     }
  1196.     if (ArgsPtr)
  1197.     {   FreeArgs(ArgsPtr);
  1198.         ArgsPtr = NULL;
  1199.     }
  1200.  
  1201.     /* Dispose the images ourselves as button.gadget doesn't
  1202.      * do this for its GA_Image...
  1203.      */
  1204.  
  1205.     for (i = 0; i <= FUNCTIONS; i++)
  1206.     {   if (image[i])
  1207.         {   DisposeObject(image[i]);
  1208.             image[i] = NULL;
  1209.     }   }
  1210.          
  1211.     if (rc == EXIT_SUCCESS)
  1212.     {   if (ConfigHandle = (BPTR) Open("PROGDIR:ReportPlus.config", MODE_NEWFILE))
  1213.         {   Write(ConfigHandle, IOBuffer, 25);
  1214.             Close(ConfigHandle);
  1215.             // ConfigHandle = NULL;
  1216.     }   }
  1217.  
  1218.     /* ReAction */
  1219.     if (WindowBase)
  1220.     {   CloseLibrary(WindowBase);
  1221.     }
  1222.     if (TextEditorBase)
  1223.     {   CloseLibrary(TextEditorBase);
  1224.     }
  1225.     if (StringBase)
  1226.     {   CloseLibrary(StringBase);
  1227.     }
  1228.     if (SpaceBase)
  1229.     {   CloseLibrary(SpaceBase);
  1230.     }
  1231.     if (ListBrowserBase)
  1232.     {   CloseLibrary(ListBrowserBase);
  1233.     }
  1234.     if (LayoutBase)
  1235.     {   CloseLibrary(LayoutBase);
  1236.     }
  1237.     if (LabelBase)
  1238.     {   CloseLibrary(LabelBase);
  1239.     }
  1240.     if (IntegerBase)
  1241.     {   CloseLibrary(IntegerBase);
  1242.     }
  1243.     if (FuelGaugeBase)
  1244.     {   CloseLibrary(FuelGaugeBase);
  1245.     }
  1246.     if (ChooserBase)
  1247.     {   CloseLibrary(ChooserBase);
  1248.     }
  1249.     if (CheckBoxBase)
  1250.     {   CloseLibrary(CheckBoxBase);
  1251.     }
  1252.     if (ButtonBase)
  1253.     {   CloseLibrary(ButtonBase);
  1254.     }
  1255.     if (BitMapBase)
  1256.     {   CloseLibrary(BitMapBase);
  1257.     }
  1258.  
  1259.     if (BoardsBase)
  1260.         CloseLibrary((struct Library *) BoardsBase);
  1261.     if (IconBase)
  1262.         CloseLibrary((struct Library *) IconBase);
  1263.     if (IFFParseBase)
  1264.         CloseLibrary((struct Library *) IFFParseBase);
  1265.     if (ASLBase)
  1266.         CloseLibrary((struct Library *) ASLBase);
  1267.     if (GadToolsBase)
  1268.         CloseLibrary((struct Library *) GadToolsBase);
  1269.     if (IntuitionBase)
  1270.     {   OpenWorkBench();
  1271.         CloseLibrary((struct Library *) IntuitionBase);
  1272.     }
  1273.  
  1274.     exit(rc); /* End of program. */
  1275. }
  1276.  
  1277. MODULE void clearkybd(void)
  1278. {   struct IntuiMessage* MsgPtr;
  1279.  
  1280.     while (MsgPtr = (struct IntuiMessage *) GT_GetIMsg(MainWindowPtr->UserPort))
  1281.         GT_ReplyIMsg(MsgPtr);
  1282. }
  1283.  
  1284. AGLOBAL void FreeNameNodes(struct List* ListPtr)
  1285. {   /* RKM Libraries, p. 496:
  1286.     
  1287.     "Free the entire list, including the header. The header is not
  1288.     updated as the list is freed. This function demonstrates how to
  1289.     avoid referencing freed memory when deallocating nodes." */
  1290.  
  1291.     struct NameNode *WorkNodePtr, *NextNodePtr;
  1292.     
  1293.     WorkNodePtr = (struct NameNode *) (ListPtr->lh_Head); /* first node */
  1294.     while (NextNodePtr = (struct NameNode *) (WorkNodePtr->nn_Node.ln_Succ))
  1295.     {   FreeMem(WorkNodePtr, sizeof(struct NameNode));
  1296.         WorkNodePtr = NextNodePtr;
  1297.     }
  1298.     NewList(ListPtr);
  1299. }
  1300. AGLOBAL void FreePathnameNodes(struct List* ListPtr)
  1301. {   struct PathnameNode *WorkNodePtr, *NextNodePtr;
  1302.     
  1303.     WorkNodePtr = (struct PathnameNode *) (ListPtr->lh_Head); /* first node */
  1304.     while (NextNodePtr = (struct PathnameNode *) (WorkNodePtr->Node.ln_Succ))
  1305.     {   FreeMem(WorkNodePtr, sizeof(struct PathnameNode));
  1306.         WorkNodePtr = NextNodePtr;
  1307.     }
  1308.     NewList(ListPtr);
  1309. }
  1310. AGLOBAL void helpabout(void)
  1311. {   PERSIST ABOOL       first = TRUE;
  1312.  
  1313.     if (AboutWindowPtr)
  1314.     {   return;
  1315.     }
  1316.  
  1317.     lockscreen();
  1318.     if (first)
  1319.     {   if (!(image[FUNCTIONS] = NewObject
  1320.         (   BITMAP_GetClass(), NULL,
  1321.             BITMAP_SourceFile, imagename[FUNCTIONS],
  1322.             BITMAP_Width,      44,
  1323.             BITMAP_Height,     38,
  1324.             BITMAP_Screen,     ScreenPtr,
  1325.         TAG_DONE)
  1326.         ))
  1327.         {   rq("Can't create ReAction image!");
  1328.         }
  1329.         GetAttr(BITMAP_BitMap, image[FUNCTIONS], (ULONG *) &bitmap[FUNCTIONS]);
  1330.         first = FALSE;
  1331.     }
  1332.  
  1333.     if (!(AboutWinObject = NewObject(WINDOW_GetClass(), NULL,
  1334.         // window tags
  1335.         WA_PubScreen,             ScreenPtr,
  1336.         WA_ScreenTitle,           TITLEBARTEXT,
  1337.         WA_Title,                 "About Report+",
  1338.         WA_Activate,              TRUE,
  1339.         WA_DepthGadget,           TRUE,
  1340.         WA_DragBar,               TRUE,
  1341.         WA_CloseGadget,           TRUE,
  1342.         WINDOW_Position,          WPOS_CENTERSCREEN,
  1343.         WINDOW_ParentGroup,
  1344.         NewObject
  1345.         (   LAYOUT_GetClass(),         NULL,
  1346.             LAYOUT_Orientation,        LAYOUT_ORIENT_HORIZ,
  1347.             LAYOUT_SpaceOuter,         TRUE,
  1348.             LAYOUT_DeferLayout,        TRUE,
  1349.             LAYOUT_AddChild,
  1350.             NewObject
  1351.             (   LAYOUT_GetClass(),     NULL,
  1352.                 // layout tags
  1353.                 LAYOUT_Orientation,    LAYOUT_ORIENT_VERT,
  1354.                 LAYOUT_SpaceOuter,     TRUE,
  1355.                 LAYOUT_DeferLayout,    TRUE,
  1356.                 LAYOUT_VertAlignment,  LALIGN_CENTER,
  1357.                 LAYOUT_AddImage,
  1358.                 NewObject
  1359.                 (   BITMAP_GetClass(),   NULL,
  1360.                     // bitmap tags
  1361.                     BITMAP_BitMap,       bitmap[FUNCTIONS],
  1362.                     BITMAP_Width,        44,
  1363.                     BITMAP_Height,       38,
  1364.                     TAG_DONE
  1365.                 ),
  1366.                 TAG_DONE
  1367.             ),
  1368.             LAYOUT_AddChild,
  1369.             NewObject
  1370.             (   LAYOUT_GetClass(), NULL,
  1371.                 // layout tags
  1372.                 LAYOUT_Orientation,    LAYOUT_ORIENT_VERT,
  1373.                 LAYOUT_SpaceOuter,     TRUE,
  1374.                 LAYOUT_DeferLayout,    TRUE,
  1375.                 LAYOUT_AddChild,
  1376.                 NewObject
  1377.                 (   LAYOUT_GetClass(), NULL,
  1378.                     // layout tags
  1379.                     LAYOUT_Orientation,    LAYOUT_ORIENT_HORIZ,
  1380.                     LAYOUT_DeferLayout,    TRUE,
  1381.                     LAYOUT_AddImage,
  1382.                     NewObject
  1383.                     (   LABEL_GetClass(),    NULL,
  1384.                         // label tags
  1385.                         LABEL_Justification, LJ_CENTRE,
  1386.                         LABEL_Text,          TITLEBARTEXT,
  1387.                         TAG_END
  1388.                     ),
  1389.                     TAG_END
  1390.                 ),
  1391.                 LAYOUT_AddChild,
  1392.                 NewObject
  1393.                 (   LAYOUT_GetClass(),       NULL,
  1394.                     LAYOUT_Orientation,      LAYOUT_ORIENT_HORIZ,
  1395.                     LAYOUT_DeferLayout,      TRUE,
  1396.                     LAYOUT_AddImage,
  1397.                     NewObject
  1398.                     (   LABEL_GetClass(),    NULL,
  1399.                         LABEL_Justification, LJ_CENTRE,
  1400.                         LABEL_Text,          "Saturday 15 February 2003",
  1401.                     TAG_END),
  1402.                 TAG_END),
  1403.                 LAYOUT_AddChild,
  1404.                 NewObject
  1405.                 (   LAYOUT_GetClass(),       NULL,
  1406.                     LAYOUT_Orientation,      LAYOUT_ORIENT_HORIZ,
  1407.                     LAYOUT_DeferLayout,      TRUE,
  1408.                     LAYOUT_AddImage,
  1409.                     NewObject
  1410.                     (   LABEL_GetClass(),    NULL,
  1411.                         // label tags
  1412.                         LABEL_Justification, LJ_CENTRE,
  1413.                         LABEL_Text,          " ",
  1414.                         TAG_END
  1415.                     ),
  1416.                     TAG_END
  1417.                 ),
  1418.                 LAYOUT_AddChild,
  1419.                 NewObject
  1420.                 (   LAYOUT_GetClass(), NULL,
  1421.                     // layout tags
  1422.                     LAYOUT_Orientation,    LAYOUT_ORIENT_HORIZ,
  1423.                     LAYOUT_DeferLayout,    TRUE,
  1424.                     LAYOUT_AddImage,
  1425.                     NewObject
  1426.                     (   LABEL_GetClass(),    NULL,
  1427.                         // label tags
  1428.                         LABEL_Justification, LJ_CENTRE,
  1429.                         LABEL_Text,          "© 2003 Amigan Software",
  1430.                         TAG_END
  1431.                     ),
  1432.                     TAG_END
  1433.                 ),
  1434.                 LAYOUT_AddChild,
  1435.                 NewObject
  1436.                 (   LAYOUT_GetClass(), NULL,
  1437.                     // layout tags
  1438.                     LAYOUT_Orientation,    LAYOUT_ORIENT_HORIZ,
  1439.                     LAYOUT_DeferLayout,    TRUE,
  1440.                     LAYOUT_AddImage,
  1441.                     NewObject
  1442.                     (   LABEL_GetClass(),    NULL,
  1443.                         // label tags
  1444.                         LABEL_Justification, LJ_CENTRE,
  1445.                         LABEL_Text,          "By James R. Jacobs",
  1446.                         TAG_END
  1447.                     ),
  1448.                     TAG_END
  1449.                 ),
  1450.                 TAG_DONE
  1451.             ),
  1452.             TAG_DONE
  1453.         ),
  1454.         TAG_DONE
  1455.     )))
  1456.     {   rq("Can't create ReAction objects!");
  1457.     }
  1458.     unlockscreen();
  1459.  
  1460.     if (!(AboutWindowPtr = (struct Window *) DoMethod((Object *) AboutWinObject, WM_OPEN, NULL)))
  1461.     {   rq("Can't open ReAction window!");
  1462.     }
  1463.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_HELP, IN_ABOUT, NOSUB));
  1464.  
  1465.     // Obtain the window wait signal mask.
  1466.     GetAttr(WINDOW_SigMask, AboutWinObject, &aboutsignal);
  1467. }
  1468.  
  1469. AGLOBAL void closewindow(void)
  1470. {   if (MainWindowPtr)
  1471.     {   clearkybd();
  1472.  
  1473.         /* Any point doing these menu functions, since we about to close the window? */
  1474.         OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_NEW,                   NOSUB));
  1475.         OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_OPEN,                  NOSUB));
  1476.         OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVE,                  NOSUB));
  1477.         OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVEAS,                NOSUB));
  1478.          OnMenu(MainWindowPtr, FULLMENUNUM(MN_TOOLS,   itemnum[shared.function], NOSUB));
  1479.  
  1480.         /* Disposing of the window object will also close the window if it is
  1481.          * already opened, and it will dispose of the layout object attached to it.
  1482.          */
  1483.         DisposeObject(WinObject[shared.function]);
  1484.         WinObject[shared.function] = NULL;
  1485.         MainWindowPtr = NULL;
  1486. }   }
  1487.  
  1488. AGLOBAL ABOOL asl(STRPTR pattern)
  1489. {   struct FileRequester* ASLRqPtr;
  1490.     ABOOL                 success;
  1491.  
  1492.     /* asldir is the directory that the ASL requester will start in. */
  1493.  
  1494.     if (!(ASLRqPtr = AllocAslRequestTags(ASL_FileRequest, ASL_Pattern, pattern, ASL_Window, MainWindowPtr, TAG_DONE)))
  1495.         rq("Can't create ASL request!");
  1496.     if
  1497.     (   AslRequestTags(ASLRqPtr, ASL_Dir, asldir, ASL_Hail, "Report+ file selector", ASL_FuncFlags, FILF_PATGAD, TAG_DONE)
  1498.      && *(ASLRqPtr->rf_File) != 0
  1499.     )
  1500.     {   strcpy(asldir, ASLRqPtr->rf_Dir);
  1501.         strcpy(aslresult, ASLRqPtr->rf_Dir);
  1502.         if (!AddPart(aslresult, ASLRqPtr->rf_File, PATHNAMEFIELD))
  1503.         {   FreeAslRequest(ASLRqPtr);
  1504.             rq("Can't add filename to pathname!");
  1505.         }
  1506.         success = TRUE;
  1507.     } else
  1508.     {   // either the user chose Cancel, or clicked OK with an empty filename
  1509.         strcpy(aslresult, "");
  1510.         success = FALSE;
  1511.     }
  1512.     // assert(ASLRqPtr);
  1513.     FreeAslRequest(ASLRqPtr);
  1514.     return(success);
  1515. }
  1516.  
  1517. AGLOBAL void loop(void)
  1518. {   SWORD oldpage = page;
  1519.     UWORD code;
  1520.     ULONG result;
  1521.  
  1522.     closer = page;
  1523.     done = FALSE;
  1524.     while (page == oldpage && !done)
  1525.     {   if (AboutWindowPtr)
  1526.         {   about_loop();
  1527.         } else
  1528.         {   if ((Wait(signal | SIGBREAKF_CTRL_C)) & SIGBREAKF_CTRL_C)
  1529.             {   done = TRUE;
  1530.                 /* should we clear the Ctrl-C signal? */
  1531.         }   }
  1532.         while ((result = DoMethod(WinObject[shared.function], WM_HANDLEINPUT, &code)) != WMHI_LASTMSG)
  1533.         {   switch (result & WMHI_CLASSMASK)
  1534.             {
  1535.             case WMHI_MENUPICK:
  1536.                 handlemenus(code);
  1537.             break;
  1538.             case WMHI_CLOSEWINDOW:
  1539.                 if (page == 31)
  1540.                 {   acse_closewindow();
  1541.                 } elif (page == 0)
  1542.                 {   cleanexit(EXIT_SUCCESS);
  1543.                 } elif (page == 1)
  1544.                 {   if (shared.function == 1)
  1545.                     {   page = 11;
  1546.                     } else
  1547.                     {   assert(shared.function == 3);
  1548.                         page = 32;
  1549.                 }   }
  1550.                 else page = 0;
  1551.             break;
  1552.             case WMHI_GADGETUP:
  1553.                 if (page == 1)
  1554.                 {   sender_loop(result & WMHI_GADGETMASK);
  1555.                 } else
  1556.                 {   switch(shared.function)
  1557.                     {
  1558.                     case 0:
  1559.                         menu_loop(result & WMHI_GADGETMASK);
  1560.                     break;
  1561.                     case 1:
  1562.                         report_ra_loop(result & WMHI_GADGETMASK);
  1563.                     break;
  1564.                     case 2:
  1565.                         aminet_loop(result & WMHI_GADGETMASK);
  1566.                     break;
  1567.                     case 3:
  1568.                         acse_loop(result & WMHI_GADGETMASK);
  1569.                     break;
  1570.                     case 4:
  1571.                         icon_loop(result & WMHI_GADGETMASK);
  1572.                     break;
  1573.                     case 5:
  1574.                         manuf_loop(result & WMHI_GADGETMASK);
  1575.                     break;
  1576.                     case 6:
  1577.                         iff_loop(result & WMHI_GADGETMASK);
  1578.                     break;
  1579.                     case 7:
  1580.                         eol_loop(result & WMHI_GADGETMASK);
  1581.                     break;
  1582.                     case 8:
  1583.                         size_loop(result & WMHI_GADGETMASK);
  1584.                     break;
  1585.                     case 9:
  1586.                         batt_loop(result & WMHI_GADGETMASK);
  1587.                     break;
  1588.                     case 10:
  1589.                         files_loop(result & WMHI_GADGETMASK);
  1590.                     break;
  1591.                     default:
  1592.                         assert(0);
  1593.                     break;
  1594.                 }   }
  1595.             break;
  1596.             default:
  1597.             break;
  1598. }   }   }   }
  1599.  
  1600. AGLOBAL ABOOL readin(STRPTR pathname)
  1601. {   BPTR FileHandle;
  1602.  
  1603.     if (!(FileHandle = (BPTR) Open(pathname, MODE_OLDFILE)))
  1604.         return FALSE;
  1605.     if (Read(FileHandle, IOBuffer, LONGESTFIELD) == -1)
  1606.     /* Limitation: the whole file must be < 16K */
  1607.     {   Close(FileHandle);
  1608.         return FALSE;
  1609.     }
  1610.     Close(FileHandle);
  1611.     return TRUE;
  1612. }
  1613.  
  1614. AGLOBAL void writeout(STRPTR pathname)
  1615. {   BPTR FileHandle;
  1616.  
  1617.     if (!(FileHandle = (BPTR) Open(pathname, MODE_NEWFILE)))
  1618.         rq("Can't open file for writing!");
  1619.     if (Write(FileHandle, IOBuffer, strlen(IOBuffer)) == -1)
  1620.     {   Close(FileHandle);
  1621.         rq("Can't write to file!");
  1622.     }
  1623.     Close(FileHandle);
  1624. }
  1625.  
  1626. AGLOBAL void rq(STRPTR text)
  1627. {   EasyStruct.es_TextFormat = text;
  1628.     EasyRequest(MainWindowPtr, &EasyStruct, NULL);
  1629.  
  1630.     cleanexit(EXIT_FAILURE);
  1631. }
  1632.  
  1633. AGLOBAL void readordie(STRPTR pathname)
  1634. {   BPTR LocalFileHandle;
  1635.  
  1636.     if (!(LocalFileHandle = (BPTR) Open(pathname, MODE_OLDFILE)))
  1637.         rq("Can't open file for reading!");
  1638.     if (Read(LocalFileHandle, IOBuffer, LONGESTFIELD) == -1)
  1639.     {   Close(LocalFileHandle);
  1640.         rq("Can't read file!");
  1641.     }
  1642.     Close(LocalFileHandle);
  1643. }
  1644.  
  1645. MODULE void parsewb(void)
  1646. {   struct DiskObject* DiskObject;
  1647.     STRPTR*            ToolArray;
  1648.     STRPTR             s;
  1649.  
  1650.     if ((*WBArg->wa_Name) && (DiskObject = GetDiskObject(WBArg->wa_Name)))
  1651.     {   ToolArray = (STRPTR *) DiskObject->do_ToolTypes;
  1652.  
  1653.         if (s = FindToolType((CONST_STRPTR *) ToolArray, "PUBSCREEN"))
  1654.             strcpy(pubscreen, s);
  1655.         if (s = FindToolType((CONST_STRPTR *) ToolArray, "NOLOGO"))
  1656.             logo = FALSE;
  1657.         if (s = FindToolType((CONST_STRPTR *) ToolArray, "ICONTYPE"))
  1658.         {   if (MatchToolValue(s, "DISK"))
  1659.             {   icon.type = WBDISK - 1;
  1660.             } elif (MatchToolValue(s, "DRAWER"))
  1661.             {   icon.type = WBDRAWER - 1;
  1662.             } elif (MatchToolValue(s, "TOOL"))
  1663.             {   icon.type = WBTOOL - 1;
  1664.             } elif (MatchToolValue(s, "PROJECT"))
  1665.             {   icon.type = WBPROJECT - 1;
  1666.             } elif (MatchToolValue(s, "TRASHCAN"))
  1667.             {   icon.type = WBGARBAGE - 1;
  1668.             } elif (MatchToolValue(s, "DEVICE"))
  1669.             {   icon.type = WBDEVICE - 1;
  1670.             } elif (MatchToolValue(s, "KICKSTART"))
  1671.             {   icon.type = WBKICK - 1;
  1672.             } elif (MatchToolValue(s, "APPICON"))
  1673.             {   icon.type = WBAPPICON - 1;
  1674.         }   }
  1675.         if (s = FindToolType((CONST_STRPTR *) ToolArray, "FUNCTION"))
  1676.         {   if (MatchToolValue(s, "1"))
  1677.                 page = 11;
  1678.             elif (MatchToolValue(s, "2"))
  1679.                 page = 21;
  1680.             elif (MatchToolValue(s, "3"))
  1681.                 page = 31;
  1682.             elif (MatchToolValue(s, "4"))
  1683.                 page = 41;
  1684.             elif (MatchToolValue(s, "5"))
  1685.                 page = 51;
  1686.             elif (MatchToolValue(s, "6"))
  1687.                 page = 61;
  1688.             elif (MatchToolValue(s, "7"))
  1689.                 page = 71;
  1690.             elif (MatchToolValue(s, "8"))
  1691.                 page = 81;
  1692.             elif (MatchToolValue(s, "9"))
  1693.                 page = 91;
  1694.             elif (MatchToolValue(s, "10"))
  1695.                 page = 101;
  1696.         }
  1697.         FreeDiskObject(DiskObject);
  1698. }   }
  1699.  
  1700. AGLOBAL void getdate(void)
  1701. {   struct DateTime DateTime;
  1702.  
  1703.     DateTime.dat_Format  = FORMAT_DOS;
  1704.     DateTime.dat_Flags   = NULL;
  1705.     DateTime.dat_StrDay  = weekdaystring;
  1706.     DateTime.dat_StrDate = datestring;
  1707.     DateTime.dat_StrTime = timestring;
  1708.  
  1709.     DateStamp(&(DateTime.dat_Stamp));
  1710.     if (!DateToStr(&DateTime))
  1711.         rq("Can't convert date!");
  1712. }
  1713.  
  1714. AGLOBAL void AddNameToTail(struct List* ListPtr, STRPTR name)
  1715. {   /* RKM Libraries, p. 496:
  1716.     
  1717.     "Allocate a NameNode structure, copy the given name into the
  1718.     structure, then add it [to] the...list." */
  1719.  
  1720.     struct NameNode* NameNodePtr;
  1721.  
  1722.     if (!(NameNodePtr = AllocMem(sizeof(struct NameNode), MEMF_CLEAR)))
  1723.         rq("Out of memory!");
  1724.     strcpy(NameNodePtr->nn_Data, name);
  1725.     NameNodePtr->nn_Node.ln_Name = NameNodePtr->nn_Data;
  1726.     NameNodePtr->nn_Node.ln_Type = NT_USER;
  1727.     NameNodePtr->nn_Node.ln_Pri  = 0;
  1728.     AddTail((struct List *) ListPtr, (struct Node *) NameNodePtr);
  1729. }
  1730. AGLOBAL void AddPathnameNode(struct List* ListPtr, STRPTR name)
  1731. {   struct PathnameNode* PathnameNodePtr;
  1732.  
  1733.     if (!(PathnameNodePtr = AllocMem(sizeof(struct PathnameNode), MEMF_CLEAR)))
  1734.         rq("Out of memory!");
  1735.     strcpy(PathnameNodePtr->pathname, name);
  1736.     PathnameNodePtr->Node.ln_Name = NULL;
  1737.     PathnameNodePtr->Node.ln_Type = NT_USER;
  1738.     PathnameNodePtr->Node.ln_Pri  = 0;
  1739.     AddTail((struct List *) ListPtr, (struct Node *) PathnameNodePtr);
  1740. }
  1741.  
  1742. AGLOBAL void append(STRPTR pathname)
  1743. {   BPTR FileHandle;
  1744.  
  1745.     if (!(FileHandle = (BPTR) Open(pathname, MODE_READWRITE)))
  1746.         rq("Can't open file for appending!");
  1747.     Seek(FileHandle, 0, OFFSET_END);
  1748.     if (Write(FileHandle, IOBuffer, strlen(IOBuffer)) == -1)
  1749.     {   Close(FileHandle);
  1750.         rq("Can't append to file!");
  1751.     }
  1752.     if (!Close(FileHandle))
  1753.         rq("Can't close appended file!");
  1754. }
  1755.  
  1756. MODULE void about_loop(void)
  1757. {   UWORD code;
  1758.     ULONG result;
  1759.     ABOOL localdone = FALSE;
  1760.  
  1761.     // Processes any messages for the About... window.
  1762.  
  1763.     if ((Wait(aboutsignal | SIGBREAKF_CTRL_C)) & SIGBREAKF_CTRL_C)
  1764.     {   localdone = TRUE;
  1765.         /* should we clear the Ctrl-C signal? */
  1766.     }
  1767.     while ((result = DoMethod(AboutWinObject, WM_HANDLEINPUT, &code)) != WMHI_LASTMSG)
  1768.     {   switch (result & WMHI_CLASSMASK)
  1769.         {
  1770.         case WMHI_MENUPICK:
  1771.             ; // handlemenus(code);
  1772.         break;
  1773.         case WMHI_CLOSEWINDOW:
  1774.             localdone = TRUE;
  1775.         break;
  1776.         default:
  1777.         break;
  1778.     }   }
  1779.  
  1780.     if (localdone)
  1781.     {   DisposeObject(AboutWinObject);
  1782.         AboutWindowPtr = AboutWinObject = NULL;
  1783.         OnMenu(MainWindowPtr, FULLMENUNUM(MN_HELP, IN_ABOUT, NOSUB));
  1784. }   }
  1785.  
  1786. AGLOBAL void parse(STRPTR terminator)
  1787. {   ABOOL done = FALSE;
  1788.     ULONG dest = 0; // index in destination string
  1789.  
  1790.     while (!done)
  1791.     {   if (IOBuffer[offset] != CR)
  1792.         {   string[dest] = IOBuffer[offset];
  1793.         }
  1794.         if (!strncmp(&IOBuffer[offset], terminator, strlen(terminator)))
  1795.         {   string[dest] = 0;
  1796.             done = TRUE;
  1797.             offset += strlen(terminator);
  1798.         } elif (offset > strlen(IOBuffer)) // we are past the end of the buffer
  1799.         {   string[0] = 0;
  1800.             done = TRUE;
  1801.         } else
  1802.         {   offset++;
  1803.             if (IOBuffer[offset] != CR)
  1804.             {   dest++;
  1805. }   }   }   }
  1806.  
  1807. AGLOBAL void parsetoend(void)
  1808. {   ABOOL done      = FALSE;
  1809.     ULONG suboffset = 0;
  1810.  
  1811.     while (!done)
  1812.     {   string[suboffset] = IOBuffer[offset];
  1813.         if (offset > strlen(IOBuffer))
  1814.         {   /* EOF */
  1815.             string[suboffset] = 0;
  1816.             done = TRUE;
  1817.         } else
  1818.         {   offset++;
  1819.             suboffset++;
  1820. }   }   }
  1821.  
  1822. AGLOBAL ABOOL saveasl(STRPTR message, STRPTR pattern)
  1823. {   struct FileRequester* ASLRqPtr;
  1824.     TEXT                  tempstring[VLONGFIELD + 1];
  1825.     ABOOL                 success;
  1826.  
  1827.     strcpy(tempstring, "Report+: ");
  1828.     strcat(tempstring, message);
  1829.  
  1830.     if (!(ASLRqPtr = AllocAslRequestTags(ASL_FileRequest, ASL_Pattern, "~(#?.info)", ASL_Window, MainWindowPtr, TAG_DONE)))
  1831.         rq("Can't create ASL request!");
  1832.     if
  1833.     (   AslRequestTags(ASLRqPtr, ASL_Dir, asldir, ASL_Hail, tempstring, ASL_FuncFlags, FILF_PATGAD | FILF_SAVE, TAG_DONE)
  1834.      && *(ASLRqPtr->rf_File) != 0
  1835.     )
  1836.     {   strcpy(asldir, ASLRqPtr->rf_Dir);
  1837.         strcpy(aslresult, ASLRqPtr->rf_Dir);
  1838.         if (!AddPart(aslresult, ASLRqPtr->rf_File, PATHNAMEFIELD))
  1839.         {   FreeAslRequest(ASLRqPtr);
  1840.             rq("Can't add filename to pathname!");
  1841.         }
  1842.         success = TRUE;
  1843.     } else
  1844.     {   strcpy(aslresult, "");
  1845.         success = FALSE;
  1846.     }
  1847.     // assert(ASLRqPtr);
  1848.     FreeAslRequest(ASLRqPtr);
  1849.     return(success);
  1850. }
  1851.  
  1852. AGLOBAL void handlemenus(UWORD code)
  1853. {   SLONG i;
  1854.     /* struct MenuItem* ItemPtr; */
  1855.  
  1856.     if (code != MENUNULL) /* while (code != MENUNULL) */
  1857.     {   /* ItemPtr = ItemAddress(MenuPtr, code); */
  1858.         switch (MENUNUM(code))
  1859.         {
  1860.         case MN_PROJECT:
  1861.             switch (ITEMNUM(code))
  1862.             {
  1863.             case IN_NEW:
  1864.                 if (shared.function == 1)
  1865.                     newreport(TRUE);
  1866.                 elif (shared.function == 2)
  1867.                     newaminet(TRUE);
  1868.             break;
  1869.             case IN_OPEN:
  1870.                 if (shared.function == 1)
  1871.                     openreport();
  1872.                 elif (shared.function == 2)
  1873.                     openaminet();
  1874.                 elif (shared.function == 9)
  1875.                     batt_open();
  1876.             break;
  1877.             case IN_SAVE:
  1878.                 if (shared.function == 1)
  1879.                     savereport(FALSE);
  1880.                 elif (shared.function == 2)
  1881.                     saveaminet(FALSE);
  1882.                 elif (shared.function == 9)
  1883.                     batt_save(FALSE);
  1884.             break;
  1885.             case IN_SAVEAS:
  1886.                 if (shared.function == 1)
  1887.                     savereport(TRUE);
  1888.                 elif (shared.function == 2)
  1889.                     saveaminet(TRUE);
  1890.                 elif (shared.function == 9)
  1891.                     batt_save(TRUE);
  1892.             break;
  1893.             case IN_QUIT:
  1894.                 cleanexit(EXIT_SUCCESS);
  1895.             break;
  1896.             default:
  1897.             break;
  1898.             }
  1899.         break;
  1900.         case MN_TOOLS:
  1901.             switch(shared.function)
  1902.             {
  1903.             case 1:
  1904.                 readreportgadgets();
  1905.             break;
  1906.             case 2:
  1907.                 readaminetgadgets();
  1908.             break;
  1909.             default:
  1910.             break;
  1911.             }
  1912.  
  1913.             closewindow();
  1914.  
  1915.             switch(shared.function)
  1916.             {
  1917.             case 3:
  1918.                 acse_exit();
  1919.             break;
  1920.             case 6:
  1921.                 iff_exit();
  1922.             break;
  1923.             case 8:
  1924.                 size_exit();
  1925.             break;
  1926.             case 10:
  1927.                 files_exit();
  1928.             break;
  1929.             }
  1930.  
  1931.             for (i = 0; i <= FUNCTIONS; i++)
  1932.             {   if (ITEMNUM(code) == itemnum[i])
  1933.                 {   if (i == 0)
  1934.                     {   page = 0;
  1935.                     } else page = (i * 10) + 1;
  1936.                     break;
  1937.             }   }
  1938.  
  1939.             done = acsestop = TRUE;
  1940.         break;
  1941.         case MN_HELP:
  1942.             switch (ITEMNUM(code))
  1943.             {
  1944.             case IN_ABOUT:
  1945.                 helpabout();
  1946.             break;
  1947.             default:
  1948.             break;
  1949.             }
  1950.         break;
  1951.         default:
  1952.         break;
  1953.         }
  1954.         /* Doing things the above way disables multi-selection,
  1955.         but prevents `endless selection'.
  1956.         code = ItemPtr->NextSelect; */
  1957. }   }
  1958.  
  1959. AGLOBAL void lockscreen(void)
  1960. {   if (pubscreen[0])
  1961.     {   if (!(ScreenPtr = LockPubScreen(pubscreen)))
  1962.         {   rq("Can't lock specified public screen!");
  1963.     }   }
  1964.     else
  1965.     {   if (!(ScreenPtr = LockPubScreen(NULL)))
  1966.         {   rq("Can't lock default public screen!");
  1967. }   }   }
  1968. AGLOBAL void unlockscreen(void)
  1969. {   if (ScreenPtr)
  1970.     {   if (pubscreen[0])
  1971.         {   UnlockPubScreen(pubscreen, ScreenPtr);
  1972.             ScreenPtr = NULL;
  1973.         } else
  1974.         {   UnlockPubScreen(NULL, ScreenPtr);
  1975.             ScreenPtr = NULL;
  1976. }   }   }
  1977.  
  1978. MODULE void eachwildcard(STRPTR subpattern, ABOOL gui)
  1979. {   struct AnchorPath* AnchorPathPtr;
  1980.     BPTR               OldDir;
  1981.     BOOL               result;
  1982.     ABOOL              done;
  1983.  
  1984.     shared.thisfile[0] = 0;
  1985.     // AnchorPathPtr must be longword aligned
  1986.     if (!(AnchorPathPtr = AllocMem(sizeof(struct AnchorPath), MEMF_ANY | MEMF_PUBLIC)))
  1987.     {   return;
  1988.     }
  1989.  
  1990.     /* We can't do the processing of the files until we have finished
  1991.     all of the Match...() calls, due to lock problems. So we build a
  1992.     list of the pathnames. */
  1993.  
  1994.     AnchorPathPtr->ap_BreakBits = NULL;
  1995.     AnchorPathPtr->ap_Flags     = NULL;
  1996.     AnchorPathPtr->ap_Strlen    = 0;
  1997.     result = MatchFirst(subpattern, AnchorPathPtr);
  1998.     if (result == 0) // 0 means success
  1999.     {   OldDir = CurrentDir(AnchorPathPtr->ap_Current->an_Lock);
  2000.         if (!NameFromLock(AnchorPathPtr->ap_Current->an_Lock, shared.thisfile, PATHNAMEFIELD))
  2001.         {   MatchEnd(AnchorPathPtr);
  2002.             return;
  2003.         }
  2004.         if (!AddPart(shared.thisfile, AnchorPathPtr->ap_Info.fib_FileName, PATHNAMEFIELD))
  2005.         {   MatchEnd(AnchorPathPtr);
  2006.             return;
  2007.         }
  2008.         CurrentDir(OldDir);
  2009.         AddPathnameNode(&FileList, shared.thisfile);
  2010.     } elif (result != ERROR_NO_MORE_ENTRIES)
  2011.     {   MatchEnd(AnchorPathPtr);
  2012.         return;
  2013.     }
  2014.  
  2015.     done = FALSE;
  2016.     while (!done)
  2017.     {   result = MatchNext(AnchorPathPtr);
  2018.         if (result == 0)
  2019.         {   OldDir = CurrentDir(AnchorPathPtr->ap_Current->an_Lock);
  2020.             if (!NameFromLock(AnchorPathPtr->ap_Current->an_Lock, shared.thisfile, PATHNAMEFIELD))
  2021.             {   MatchEnd(AnchorPathPtr);
  2022.                 return;
  2023.             }
  2024.             if (!AddPart(shared.thisfile, AnchorPathPtr->ap_Info.fib_FileName, PATHNAMEFIELD))
  2025.             {   MatchEnd(AnchorPathPtr);
  2026.                 return;
  2027.             }
  2028.             CurrentDir(OldDir);
  2029.             AddPathnameNode(&FileList, shared.thisfile);
  2030.         } elif (result != ERROR_NO_MORE_ENTRIES)
  2031.         {   MatchEnd(AnchorPathPtr);
  2032.             return;
  2033.         } else done = TRUE;
  2034.     }
  2035.     MatchEnd(AnchorPathPtr);
  2036.     FreeMem(AnchorPathPtr, sizeof(struct AnchorPath));
  2037. }
  2038.  
  2039. AGLOBAL void multiasl(STRPTR pattern)
  2040. {   struct FileRequester* ASLRqPtr;
  2041.     ULONG                 i;
  2042.     TEXT                  quotestring[2];
  2043.  
  2044.     quotestring[0] = QUOTE;
  2045.     quotestring[1] = 0;
  2046.  
  2047.     /* It would also be good to correctly
  2048.     handle selection of directories. */
  2049.  
  2050.     if (!(ASLRqPtr = AllocAslRequestTags(ASL_FileRequest, ASL_Pattern, pattern, ASL_Window, MainWindowPtr, TAG_DONE)))
  2051.         rq("Can't create ASL request!");
  2052.     if (AslRequestTags(ASLRqPtr, ASL_Dir, asldir, ASL_Hail, "Report+ file multiselector", ASL_FuncFlags, FILF_PATGAD | FILF_MULTISELECT, TAG_DONE) && *(ASLRqPtr->rf_File) != 0)
  2053.     {   if (ASLRqPtr->rf_NumArgs)
  2054.         {   /* rf_ArgList is an array of WBArg structures. Each entry in
  2055.             this array corresponds to one of the files the user selected
  2056.             (in alphabetical order). The user multiselected; step through
  2057.             the list of selected files. */
  2058.             strcpy(asldir, ASLRqPtr->rf_Dir);
  2059.             strcpy(shared.pathname, quotestring);
  2060.             strcat(shared.pathname, ASLRqPtr->rf_Dir);
  2061.             if (!AddPart(shared.pathname, (ASLRqPtr->rf_ArgList)[0].wa_Name, PATHNAMEFIELD))
  2062.             {   FreeAslRequest(ASLRqPtr);
  2063.                 rq("Can't add filename to pathname!");
  2064.             }
  2065.             strcat(shared.pathname, quotestring);
  2066.             strcat(shared.pathname, " ");
  2067.             for (i = 1; i < ASLRqPtr->rf_NumArgs; i++)
  2068.             {   strcat(shared.pathname, quotestring);
  2069.                 strcat(shared.pathname, ASLRqPtr->rf_Dir);
  2070.                 if (!AddPart(shared.pathname, (ASLRqPtr->rf_ArgList)[i].wa_Name, PATHNAMEFIELD))
  2071.                    rq("Can't add filename to pathname!");
  2072.                 strcat(shared.pathname, quotestring);
  2073.                 if (i < ASLRqPtr->rf_NumArgs - 1)
  2074.                     strcat(shared.pathname, " ");
  2075.         }   }
  2076.         else
  2077.         {   /* The user didn't multiselect; use the normal way to get the
  2078.             filename. */
  2079.  
  2080.             strcpy(asldir, ASLRqPtr->rf_Dir);
  2081.             strcpy(shared.pathname, quotestring);
  2082.             strcat(shared.pathname, ASLRqPtr->rf_Dir);
  2083.             if (!AddPart(shared.pathname, ASLRqPtr->rf_File, PATHNAMEFIELD))
  2084.             {   FreeAslRequest(ASLRqPtr);
  2085.                 rq("Can't add filename to pathname!");
  2086.             }
  2087.             strcat(shared.pathname, quotestring);
  2088.     }   }
  2089.     else
  2090.     {   ; // the user chose Cancel
  2091.     }
  2092.     // assert(ASLRqPtr);
  2093.     FreeAslRequest(ASLRqPtr);
  2094. }
  2095.  
  2096. AGLOBAL void checkabort(ABOOL gui)
  2097. {   ULONG signals, gid, result;
  2098.     UWORD code;
  2099.  
  2100.     /* OK, we've just finished operating on that file. Now before we */
  2101.     /* start on the next one, check whether the user still wants to... */
  2102.     signals = SetSignal(0L, 0L);
  2103.     if (signals & SIGBREAKF_CTRL_C)
  2104.     {   stop = TRUE;
  2105.         SetSignal(0L, SIGBREAKF_CTRL_C); /* clear the Ctrl-C signal */
  2106.         if (gui)
  2107.         {   if (shared.function == 7)
  2108.             {   SetGadgetAttrs
  2109.                 (   eol_gadgets[GID_7_ST2], MainWindowPtr, NULL,
  2110.                     STRINGA_TextVal, "Aborted by user!",
  2111.                 TAG_DONE);
  2112.             } else
  2113.             {   // assert(shared.function == 4);
  2114.                 SetGadgetAttrs
  2115.                 (   icon_gadgets[GID_4_ST2], MainWindowPtr, NULL,
  2116.                     STRINGA_TextVal, "Aborted by user!",
  2117.                 TAG_DONE);
  2118.         }   }
  2119.         else
  2120.         {   Printf("Aborted by user!\n");
  2121.             Flush(Output());
  2122.     }   }
  2123.  
  2124.     if (gui)
  2125.     {   while ((result = DoMethod(WinObject[shared.function], WM_HANDLEINPUT, &code)) != WMHI_LASTMSG)
  2126.         {   switch (result & WMHI_CLASSMASK)
  2127.             {
  2128.             case WMHI_MENUPICK:
  2129.                 ; /* handlemenus(code); */
  2130.             break;
  2131.             case WMHI_CLOSEWINDOW:
  2132.                 done = quit = TRUE;
  2133.             break;
  2134.             case WMHI_GADGETUP:
  2135.                 gid = result & WMHI_GADGETMASK;
  2136.                 if
  2137.                 (   (shared.function == 4 && gid == GID_4_BU4)
  2138.                  || (shared.function == 7 && gid == GID_7_BU4)
  2139.                 )
  2140.                 {   stop = TRUE;
  2141.                 }
  2142.             break;
  2143.             default:
  2144.             break;
  2145. }   }   }   }
  2146.  
  2147. AGLOBAL ABOOL convert(ABOOL gui)
  2148. {   ULONG        i, j, length;
  2149.     ABOOL        letters, /* are we in letters (TRUE) or whitespace (FALSE)? */
  2150.                  quoted;  /* are we quoted (TRUE) or unquoted (FALSE)? */
  2151.     struct PathnameNode* NodePtr;
  2152.  
  2153.     /* At this point we have a list of pathnames, separated by spaces and
  2154.     NULL-terminated. If they came from ASL, they will be quoted, otherwise,
  2155.     they may not. This is the raw input; it can contain anything,
  2156.     including wildcards.
  2157.  
  2158.     shared.pathname: the actual contents of the string gadget.
  2159.     shared.thatfile: each file that we pass to eachwildcard().
  2160.     shared.thisfile: each file that we pass for conversion. */
  2161.  
  2162.     stop = letters = quoted = FALSE;
  2163.     length = strlen(shared.pathname);
  2164.     j = 0;
  2165.  
  2166.     for (i = 0; i < length; i++)
  2167.     {   if (!stop)
  2168.         {   if (shared.pathname[i] == ' ' && letters && !quoted)
  2169.             {   /* if we're unquoted and have a space */
  2170.                 shared.thatfile[j] = 0; /* then NULL-terminate the pathname */
  2171.                 eachwildcard(shared.thatfile, gui);
  2172.                 j = 0;
  2173.                 letters = FALSE;
  2174.             } elif (shared.pathname[i] == QUOTE)
  2175.             {   if (!letters && !quoted)
  2176.                 {   letters = TRUE; /* we're in letters */
  2177.                     quoted = TRUE; /* it's a quote */
  2178.                 } elif (letters && quoted)
  2179.                 {   quoted = FALSE; /* it's an unquote */
  2180.             }   }
  2181.             else
  2182.             {   shared.thatfile[j++] = shared.pathname[i];
  2183.                 letters = TRUE; /* we're in letters */
  2184.     }   }   }
  2185.     /* Now we are at the end. */
  2186.     if (!stop && letters) /* if we're in letters */
  2187.     {   shared.thatfile[j] = 0;
  2188.         /* then it is ended, quoted or not. Although we could */
  2189.         /* report an error condition if there are an odd */
  2190.         /* number of quotes (ie. a missing quote). */
  2191.         eachwildcard(shared.thatfile, gui);
  2192.     }
  2193.  
  2194.     if ((FileList.lh_Head)->ln_Succ) // if the list is non-empty
  2195.     {   // Walk the list
  2196.         for
  2197.         (   NodePtr = FileList.lh_Head;
  2198.             NodePtr->Node.ln_Succ;
  2199.             NodePtr = NodePtr->Node.ln_Succ
  2200.         )
  2201.         {   if (!stop)
  2202.             {   strcpy(shared.thisfile, NodePtr->pathname);
  2203.                 if (shared.function == 7)
  2204.                 {   eolconvert(gui);
  2205.                 } else
  2206.                 {   /* assert(shared.function == 4); */
  2207.                     iconconvert(gui);
  2208.         }   }   }
  2209.         if (FileList.lh_Head->ln_Succ) // if list is non-empty
  2210.         {   FreePathnameNodes(&FileList);
  2211.         }
  2212.         return(TRUE);
  2213.     } else
  2214.     {   return(FALSE);
  2215. }   }
  2216.  
  2217. MODULE void menu_loop(ULONG gid)
  2218. {   switch (gid)
  2219.     {
  2220.     case GID_0_BU1:
  2221.         page = 11;  // bug report
  2222.     break;
  2223.     case GID_0_BU2:
  2224.         page = 21;  // Aminet readme
  2225.     break;
  2226.     case GID_0_BU3:
  2227.         page = 91;  // battery RAM
  2228.     break;
  2229.     case GID_0_BU4:
  2230.         page = 51;  // ID database
  2231.     break;
  2232.     case GID_0_BU5:
  2233.         page = 61;  // IFF FORMs
  2234.     break;
  2235.     case GID_0_BU6:
  2236.         page = 41;  // icons
  2237.     break;
  2238.     case GID_0_BU7:
  2239.         page = 71;  // EOL/tabs
  2240.     break;
  2241.     case GID_0_BU8:
  2242.         page = 81;  // path size
  2243.     break;
  2244.     case GID_0_BU9:
  2245.         page = 101; // system files
  2246.     break;
  2247.     case GID_0_BU10:
  2248.         page = 31;  // ACSE
  2249.     break;
  2250.     default:
  2251.         ; // assert(0);
  2252.     break;
  2253. }   }
  2254.  
  2255. AGLOBAL ULONG Hook0Func(struct Hook *h, VOID *o, VOID *msg)
  2256. {   /* "When the hook is called, the data argument points to the 
  2257.     window object and message argument to the IntuiMessage."
  2258.  
  2259.     These IntuiMessages do not need to be replied to by the appliprog. */
  2260.  
  2261.     AUTO    UWORD code, qual;
  2262.     AUTO    ULONG class, i;
  2263.     AUTO    SWORD mousex, mousey;
  2264.     AUTO    SLONG newover;
  2265.     PERSIST ULONG over = FUNCTIONS;
  2266.  
  2267.     geta4(); // wait till here before doing anything
  2268.  
  2269.     class  = ((struct IntuiMessage *) msg)->Class;
  2270.     code   = ((struct IntuiMessage *) msg)->Code;
  2271.     qual   = ((struct IntuiMessage *) msg)->Qualifier;
  2272.     mousex = ((struct IntuiMessage *) msg)->MouseX;
  2273.     mousey = ((struct IntuiMessage *) msg)->MouseY;
  2274.  
  2275.     switch(class)
  2276.     {
  2277.     case IDCMP_RAWKEY:
  2278.         switch(code)
  2279.         {
  2280.         case SCAN_HELP:
  2281.             helpabout();
  2282.         break;
  2283.         case SCAN_ESCAPE:
  2284.             cleanexit(EXIT_SUCCESS);
  2285.         break;
  2286.         case SCAN_GRAVE:
  2287.             if (qual & IEQUALIFIER_CONTROL)
  2288.             {   decrypt();
  2289.             }
  2290.         break;
  2291.         default:
  2292.         break;
  2293.         }
  2294.     break;
  2295.     case IDCMP_INTUITICKS:
  2296.     {   newover = FUNCTIONS;
  2297.         for (i = 0; i < FUNCTIONS; i++)
  2298.         {   if
  2299.             (   mousex >= gadgets[GID_0_BU1 + i]->LeftEdge
  2300.              && mousex <= gadgets[GID_0_BU1 + i]->LeftEdge + gadgets[GID_0_BU1 + i]->Width  - 1
  2301.              && mousey >= gadgets[GID_0_BU1 + i]->TopEdge
  2302.              && mousey <= gadgets[GID_0_BU1 + i]->TopEdge  + gadgets[GID_0_BU1 + i]->Height - 1
  2303.             )
  2304.             {   newover = i;
  2305.                 break;
  2306.         }   }
  2307.         if (newover != over)
  2308.         {   over = newover;
  2309.             SetGadgetAttrs
  2310.             (   gadgets[GID_0_ST1], MainWindowPtr, NULL,
  2311.                 STRINGA_TextVal, FunctionDesc[over],
  2312.                 TAG_DONE
  2313.             );
  2314.     }   }
  2315.     break;
  2316.     default:
  2317.     break;
  2318.     }
  2319.  
  2320.     return(1);
  2321. }
  2322.  
  2323. /* This function converts register-parameter Hook calling convention into
  2324. standard C conventions. It requires a C compiler that supports
  2325. registerized parameters, such as SAS/C 5.x or greater. */
  2326.  
  2327. AGLOBAL ULONG ASM hookEntry(REG(a0) struct Hook *h, REG(a2) VOID *o, REG(a1) VOID *msg)
  2328. {   // This is the stub function that converts the register-parameters
  2329.     // to stack parameters.
  2330.  
  2331.     return ((*(ULONG (*)(struct Hook *, VOID *, VOID *))(*h->h_SubEntry))(h, o, msg));
  2332. }
  2333.  
  2334. AGLOBAL void InitHook(struct Hook* hook, ULONG (*func)(), void* data)
  2335. {   // Make sure a pointer was passed
  2336.  
  2337.     if (hook)
  2338.     {   // Fill in the Hook fields
  2339.         hook->h_Entry    = (ULONG (*)()) hookEntry;
  2340.         hook->h_SubEntry = func;
  2341.         hook->h_Data     = data;
  2342.     } else
  2343.     {   Printf("Report+: Can't initialize hook (NULL pointer)!");
  2344.         cleanexit(EXIT_FAILURE);
  2345. }   }
  2346.  
  2347. AGLOBAL void clearlist(struct List* ListPtr)
  2348. {   if (ListPtr->lh_Head->ln_Succ) // if list is non-empty
  2349.     {   FreeNameNodes(ListPtr);
  2350.     }
  2351.     NewList(ListPtr); // prepare for reuse
  2352. }
  2353.  
  2354. // Function to free an Exec List of ReAction ListBrowser nodes.
  2355. AGLOBAL void clearreactionlist(struct List* ListPtr)
  2356. {   /* Requirements: listbrowser class must be already open, and list
  2357.     must be detached from gadget*/
  2358.  
  2359.     if (ListPtr->lh_Head->ln_Succ) // if list is non-empty
  2360.     {   FreeListBrowserList(ListPtr);
  2361.     }
  2362.     NewList(ListPtr); // prepare for reuse
  2363. }
  2364.  
  2365. AGLOBAL void openwindow(void)
  2366. {   // Opens a ReAction window.
  2367.  
  2368.     if (!(MainWindowPtr = (struct Window *) DoMethod(WinObject[shared.function], WM_OPEN, NULL)))
  2369.     {   rq("Can't open ReAction window!");        
  2370.     }
  2371.  
  2372.     // Obtain the window wait signal mask.
  2373.     GetAttr(WINDOW_SigMask, WinObject[shared.function], &signal);
  2374.  
  2375.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_NEW,                   NOSUB));
  2376.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_OPEN,                  NOSUB));
  2377.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVE,                  NOSUB));
  2378.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_PROJECT, IN_SAVEAS,                NOSUB));
  2379.     OffMenu(MainWindowPtr, FULLMENUNUM(MN_TOOLS,   itemnum[shared.function], NOSUB));
  2380. }
  2381.  
  2382. AGLOBAL ABOOL ra_checkbreak(void)
  2383. {   ULONG result;
  2384.     UWORD code;
  2385.  
  2386.     while ((result = DoMethod(WinObject[shared.function], WM_HANDLEINPUT, &code)) != WMHI_LASTMSG)
  2387.     {   switch (result & WMHI_CLASSMASK)
  2388.         {
  2389.         case IDCMP_RAWKEY:
  2390.             if (code == SCAN_ESCAPE)
  2391.                 return(1);
  2392.         break;
  2393.         case WMHI_CLOSEWINDOW:
  2394.              return(2);
  2395.         break;
  2396.         case WMHI_GADGETUP:
  2397.              if (shared.function == 8)
  2398.              {   if ((result & (WMHI_GADGETMASK)) == GID_8_BU5) // these parentheses are needed!
  2399.                  {   return(1);
  2400.              }   }
  2401.              else
  2402.              {   // assert(shared.function == 10);
  2403.                  if ((result & (WMHI_GADGETMASK)) == GID_10_BU3) // these parentheses are needed!
  2404.                  {   return(1);
  2405.              }   }
  2406.         break;
  2407.         default:
  2408.         break;
  2409.     }   }
  2410.     return(0);
  2411. }
  2412.  
  2413. AGLOBAL void sender(void)
  2414. {   struct Hook SenderHookStruct;
  2415.     STRPTR      stringptr;
  2416.  
  2417.     if (readin("S:Report.sender"))
  2418.     {   /* # Refer: <last>,<first> (<company> ,phone <phone>)<LF>
  2419.            # Path: <email><LF>
  2420.            # ReferID: <developer><LF> */
  2421.  
  2422.         offset = 0;
  2423.         parse("# Refer: ");
  2424.         parse(",");
  2425.         strcpy(report.lastname,  string);
  2426.         parse(" (");
  2427.         strcpy(report.firstname, string);
  2428.         parse(" ,phone ");
  2429.         strcpy(report.company,   string);
  2430.         parse(")\n# Path: ");
  2431.         strcpy(report.phone,     string);
  2432.         parse("\n# ReferID: ");
  2433.         strcpy(report.email,     string);
  2434.         parse("\n");
  2435.         strcpy(report.developer, string);
  2436.     }
  2437.  
  2438.     InitHook(&SenderHookStruct, SenderHookFunc, NULL);
  2439.  
  2440.     /* Create the window object. */
  2441.     lockscreen();
  2442.  
  2443. if (!(WinObject[shared.function] =
  2444. NewObject
  2445. (
  2446.     WINDOW_GetClass(),                    NULL,
  2447.     WA_PubScreen,                         ScreenPtr,
  2448.     WA_ScreenTitle,                       "Report+",
  2449.     WA_Title,                             "Report+: Sender Details",
  2450.     WA_Activate,                          TRUE,
  2451.     WA_DepthGadget,                       TRUE,
  2452.     WA_DragBar,                           TRUE,
  2453.     WA_CloseGadget,                       TRUE,
  2454.     WA_SizeGadget,                        TRUE,
  2455.     WA_IDCMP,                             IDCMP_RAWKEY,
  2456.     WINDOW_IDCMPHook,                     &SenderHookStruct,
  2457.     WINDOW_IDCMPHookBits,                 IDCMP_RAWKEY,
  2458.     WINDOW_MenuStrip,                     MenuPtr,
  2459.     WINDOW_Position,                      WPOS_CENTERSCREEN,
  2460.     WINDOW_ParentGroup,                   sender_gadgets[GID_S_LY1] =
  2461.     NewObject
  2462.     (   LAYOUT_GetClass(),                NULL,
  2463.         LAYOUT_Orientation,               LAYOUT_ORIENT_HORIZ,
  2464.         LAYOUT_SpaceOuter,                TRUE,
  2465.         LAYOUT_DeferLayout,               TRUE,
  2466.         LAYOUT_AddChild,                  NewObject(LAYOUT_GetClass(), NULL,
  2467.             LAYOUT_Orientation,           LAYOUT_ORIENT_VERT,
  2468.             LAYOUT_VertAlignment,         LALIGN_CENTER,
  2469.             LAYOUT_BevelStyle,            BVS_NONE,
  2470.             LAYOUT_AddChild,              NewObject
  2471.             (   LAYOUT_GetClass(),        NULL,
  2472.                 LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
  2473.                 LAYOUT_HorizAlignment,    LALIGN_RIGHT,
  2474.                 LAYOUT_BevelStyle,        BVS_NONE,
  2475.                 LAYOUT_AddImage,          NewObject
  2476.                 (   LABEL_GetClass(),     NULL,
  2477.                     // label
  2478.                     LABEL_Text,           "_First name:",
  2479.                     LABEL_Justification,  LJ_RIGHT,
  2480.                     TAG_END
  2481.                 ),
  2482.                 TAG_END
  2483.             ),
  2484.             CHILD_WeightedHeight,         0,
  2485.             LAYOUT_AddChild,              NewObject(LAYOUT_GetClass(), NULL,
  2486.                 // layout
  2487.                 LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
  2488.                 LAYOUT_HorizAlignment,    LALIGN_RIGHT,
  2489.                 LAYOUT_BevelStyle,        BVS_NONE,
  2490.                 LAYOUT_AddImage,          NewObject
  2491.                 (   LABEL_GetClass(),     NULL,
  2492.                     // label
  2493.                     LABEL_Text,           "_Last name:",
  2494.                     LABEL_Justification,  LJ_RIGHT,
  2495.                     TAG_END
  2496.                 ),
  2497.             TAG_END),
  2498.             CHILD_WeightedHeight,         0,
  2499.             LAYOUT_AddChild,
  2500.             NewObject
  2501.             (   LAYOUT_GetClass(),        NULL,
  2502.                 LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
  2503.                 LAYOUT_HorizAlignment,    LALIGN_RIGHT,
  2504.                 LAYOUT_BevelStyle,        BVS_NONE,
  2505.                 LAYOUT_AddImage,          NewObject
  2506.                 (   LABEL_GetClass(),     NULL,
  2507.                     // label
  2508.                     LABEL_Text,           "_Company:",
  2509.                     LABEL_Justification,  LJ_RIGHT,
  2510.                     TAG_END
  2511.                 ),
  2512.                 TAG_END
  2513.             ),
  2514.             CHILD_WeightedHeight,         0,
  2515.             LAYOUT_AddChild,              NewObject(LAYOUT_GetClass(), NULL,
  2516.                 // layout
  2517.                 LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
  2518.                 LAYOUT_HorizAlignment,    LALIGN_RIGHT,
  2519.                 LAYOUT_BevelStyle,        BVS_NONE,
  2520.                 LAYOUT_AddImage,          NewObject
  2521.                 (   LABEL_GetClass(),     NULL,
  2522.                     // label
  2523.                     LABEL_Text,           "_Phone number:",
  2524.                     LABEL_Justification,  LJ_RIGHT,
  2525.                     TAG_END
  2526.                 ),
  2527.                 TAG_END
  2528.             ),
  2529.             CHILD_WeightedHeight,         0,
  2530.             LAYOUT_AddChild,
  2531.             NewObject
  2532.             (   LAYOUT_GetClass(),        NULL,
  2533.                 LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
  2534.                 LAYOUT_HorizAlignment,    LALIGN_RIGHT,
  2535.                 LAYOUT_BevelStyle,        BVS_NONE,
  2536.                 LAYOUT_AddImage,          NewObject
  2537.                 (   LABEL_GetClass(),     NULL,
  2538.                     // label
  2539.                     LABEL_Text,           "_Developer number:",
  2540.                     LABEL_Justification,  LJ_RIGHT,
  2541.                     TAG_END
  2542.                 ),
  2543.                 TAG_END
  2544.             ),
  2545.             CHILD_WeightedHeight,         0,
  2546.             LAYOUT_AddChild,
  2547.             NewObject
  2548.             (   LAYOUT_GetClass(),        NULL,
  2549.                 LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
  2550.                 LAYOUT_HorizAlignment,    LALIGN_RIGHT,
  2551.                 LAYOUT_BevelStyle,        BVS_NONE,
  2552.                 LAYOUT_AddImage,          NewObject
  2553.                 (   LABEL_GetClass(),     NULL,
  2554.                     // label
  2555.                     LABEL_Text,           "_Email:",
  2556.                     LABEL_Justification,  LJ_RIGHT,
  2557.                 TAG_END),
  2558.             TAG_END),
  2559.             CHILD_WeightedHeight,         0,
  2560.         TAG_END),
  2561.         CHILD_WeightedWidth,              0,
  2562.         LAYOUT_AddChild,
  2563.         NewObject
  2564.         (   LAYOUT_GetClass(),        NULL,
  2565.             LAYOUT_Orientation,       LAYOUT_ORIENT_VERT,
  2566.             LAYOUT_VertAlignment,     LALIGN_CENTER,
  2567.             LAYOUT_HorizAlignment,    LALIGN_CENTER,
  2568.             LAYOUT_BevelStyle,        BVS_NONE,
  2569.             LAYOUT_AddChild,          sender_gadgets[GID_S_ST1] =
  2570.             NewObject
  2571.             (   STRING_GetClass(),    NULL,
  2572.                 GA_ID,                GID_S_ST1,
  2573.                 STRINGA_TextVal,      report.firstname,
  2574.                 STRINGA_MinVisible,   20,
  2575.                 STRINGA_MaxChars,     MEDFIELD,
  2576.                 GA_TabCycle,          TRUE,
  2577.             TAG_END),
  2578.             LAYOUT_AddChild,          sender_gadgets[GID_S_ST2] =
  2579.             NewObject
  2580.             (   STRING_GetClass(),    NULL,
  2581.                 GA_ID,                GID_S_ST2,
  2582.                 STRINGA_TextVal,      report.lastname,
  2583.                 STRINGA_MinVisible,   20,
  2584.                 STRINGA_MaxChars,     MEDFIELD,
  2585.                 GA_TabCycle,          TRUE,
  2586.             TAG_END),
  2587.             LAYOUT_AddChild,          sender_gadgets[GID_S_ST3] =
  2588.             NewObject
  2589.             (   STRING_GetClass(),    NULL,
  2590.                 GA_ID,                GID_S_ST3,
  2591.                 STRINGA_TextVal,      report.company,
  2592.                 STRINGA_MinVisible,   20,
  2593.                 STRINGA_MaxChars,     MEDFIELD,
  2594.                 GA_TabCycle,          TRUE,
  2595.             TAG_END),
  2596.             LAYOUT_AddChild,          sender_gadgets[GID_S_ST4] =
  2597.             NewObject
  2598.             (   STRING_GetClass(),    NULL,
  2599.                 GA_ID,                GID_S_ST4,
  2600.                 STRINGA_TextVal,      report.phone,
  2601.                 STRINGA_MinVisible,   20,
  2602.                 STRINGA_MaxChars,     MEDFIELD,
  2603.                 GA_TabCycle,          TRUE,
  2604.             TAG_END),
  2605.             LAYOUT_AddChild,          sender_gadgets[GID_S_ST5] =
  2606.             NewObject
  2607.             (   STRING_GetClass(),    NULL,
  2608.                 GA_ID,                GID_S_ST5,
  2609.                 STRINGA_TextVal,      report.developer,
  2610.                 STRINGA_MinVisible,   20,
  2611.                 STRINGA_MaxChars,     MEDFIELD,
  2612.                 GA_TabCycle,          TRUE,
  2613.             TAG_END),
  2614.             LAYOUT_AddChild,          sender_gadgets[GID_S_ST6] =
  2615.             NewObject
  2616.             (   STRING_GetClass(),    NULL,
  2617.                 GA_ID,                GID_S_ST6,
  2618.                 STRINGA_TextVal,      report.email,
  2619.                 STRINGA_MinVisible,   20,
  2620.                 STRINGA_MaxChars,     MEDFIELD,
  2621.                 GA_TabCycle,          TRUE,
  2622.             TAG_END),
  2623.         TAG_END),
  2624.         CHILD_WeightedHeight,     0,
  2625.     TAG_END)
  2626. )))
  2627. {   rq("Can't create ReAction gadgets!");
  2628. }
  2629. unlockscreen();
  2630. openwindow();
  2631.  
  2632.     ActivateLayoutGadget(sender_gadgets[GID_S_LY1], MainWindowPtr, NULL, (Object) sender_gadgets[GID_S_ST1]);
  2633.     loop();
  2634.  
  2635.     /* write out S:Report.sender
  2636.     # Refer: <last>,<first> (<company> ,phone <phone>)<LF>
  2637.     # Path: <email><LF>
  2638.     # ReferID: <developer><LF> */
  2639.  
  2640.     strcpy(report.refer, "# Refer: ");
  2641.     if (!(GetAttr
  2642.     (   STRINGA_TextVal, sender_gadgets[GID_S_ST2], (ULONG *) &stringptr
  2643.     )))
  2644.     {   rq("Unsupported inquiry!"); // should never happen
  2645.     }
  2646.     strcat(report.refer, stringptr);
  2647.     strcat(report.refer, ",");
  2648.     if (!(GetAttr
  2649.     (   STRINGA_TextVal, sender_gadgets[GID_S_ST1], (ULONG *) &stringptr
  2650.     )))
  2651.     {   rq("Unsupported inquiry!"); // should never happen
  2652.     }
  2653.     strcat(report.refer, stringptr);
  2654.     strcat(report.refer, " (");
  2655.     if (!(GetAttr
  2656.     (   STRINGA_TextVal, sender_gadgets[GID_S_ST3], (ULONG *) &stringptr
  2657.     )))
  2658.     {   rq("Unsupported inquiry!"); // should never happen
  2659.     }
  2660.     strcat(report.refer, stringptr);
  2661.     strcat(report.refer, " ,phone ");
  2662.     if (!(GetAttr
  2663.     (   STRINGA_TextVal, sender_gadgets[GID_S_ST4], (ULONG *) &stringptr
  2664.     )))
  2665.     {   rq("Unsupported inquiry!"); // should never happen
  2666.     }
  2667.     strcat(report.refer, stringptr);
  2668.     strcat(report.refer, ")\n");
  2669.  
  2670.     if (!(GetAttr
  2671.     (   STRINGA_TextVal, sender_gadgets[GID_S_ST6], (ULONG *) &stringptr
  2672.     )))
  2673.     {   rq("Unsupported inquiry!"); // should never happen
  2674.     }
  2675.     strcpy(report.path, "# Path: ");
  2676.     strcat(report.path, stringptr);
  2677.     strcat(report.path, "\n");
  2678.  
  2679.     if (!(GetAttr
  2680.     (   STRINGA_TextVal, sender_gadgets[GID_S_ST5], (ULONG *) &stringptr
  2681.     )))
  2682.     {   rq("Unsupported inquiry!"); // should never happen
  2683.     }
  2684.     strcpy(report.referid, "# ReferID: ");
  2685.     strcat(report.referid, stringptr);
  2686.     strcat(report.referid, "\n");
  2687.  
  2688.     strcpy(IOBuffer, report.refer);
  2689.     strcat(IOBuffer, report.path);
  2690.     strcat(IOBuffer, report.referid);
  2691.     
  2692.     writeout("S:Report.sender");
  2693.  
  2694.     closewindow();
  2695. }
  2696.  
  2697. MODULE void sender_loop(ULONG gid)
  2698. {   ;
  2699. }
  2700.  
  2701. AGLOBAL void getversion(STRPTR filename, STRPTR output)
  2702. {   ULONG i;
  2703.     TEXT  commandstring[PATHNAMEFIELD + 1];
  2704.  
  2705.     /* If you have any lock on the file or its directory, this function
  2706.     will fail (returning "?"). */
  2707.  
  2708.     if (ram)
  2709.     {   strcpy(commandstring, "RAM:Version ");
  2710.     } else
  2711.     {   strcpy(commandstring, "Version ");
  2712.     }
  2713.     strcat(commandstring, filename);
  2714.     strcat(commandstring, " >T:ReportPlus.temp");
  2715.     if (!SystemTags(commandstring, SYS_Output, Open("NIL:", MODE_NEWFILE), TAG_DONE))
  2716.     {   readordie("T:ReportPlus.temp");
  2717.         for (i = 0; i <= VLONGFIELD; i++)
  2718.         {   if (IOBuffer[i] == LF)
  2719.             {   IOBuffer[i] = 0;
  2720.                 break;
  2721.         }   }
  2722.         strcpy(output, IOBuffer);
  2723.     } else
  2724.     {   strcpy(output, "?");
  2725. }   }
  2726.  
  2727. AGLOBAL void setbar(ULONG max)
  2728. {   // Ensure we do no more than BARUPDATES updates of the progress bar.
  2729.  
  2730.     increment = max / BARUPDATES;
  2731.     if (increment == 0)
  2732.     {   increment = 1;
  2733. }   }
  2734.  
  2735. AGLOBAL ABOOL dirasl(void)
  2736. {   struct FileRequester* ASLRqPtr;
  2737.     ABOOL                 success;
  2738.  
  2739.     if (!(ASLRqPtr = AllocAslRequestTags(ASL_FileRequest, ASL_Pattern, "#?", ASL_Window, MainWindowPtr, ASL_ExtFlags1, FIL1F_NOFILES, TAG_DONE)))
  2740.     {   rq("Can't create ASL request!");
  2741.     }
  2742.     if (AslRequestTags(ASLRqPtr, ASL_Dir, asldir, ASL_Hail, "Report+ path selector", ASL_FuncFlags, FILF_PATGAD, TAG_DONE))
  2743.     {   strcpy(aslresult, ASLRqPtr->rf_Dir);
  2744.         success = TRUE;
  2745.     } else success = FALSE;
  2746.     FreeAslRequest(ASLRqPtr);
  2747.     return(success);
  2748. }
  2749.  
  2750. AGLOBAL void comma(ULONG value, STRPTR commastring)
  2751. {   ABOOL yes = FALSE;
  2752.     TEXT  valuestring[11];
  2753.  
  2754.     strcpy(commastring, " ,   ,   ,   ");
  2755.     //                    1   5   9
  2756.  
  2757.     valuestring[ 0] = '0' + (value / 1000000000);
  2758.     value %= 1000000000;
  2759.     if (valuestring[ 0] != '0')
  2760.     {   commastring[0] = valuestring[0];
  2761.         yes = TRUE;
  2762.     } else
  2763.     {   commastring[ 0] = ' ';
  2764.         commastring[ 1] = ' ';
  2765.     }
  2766.  
  2767.     valuestring[ 1] = '0' + (value /  100000000);
  2768.     value %=  100000000;
  2769.     if (yes || valuestring[1] != '0')
  2770.     {   commastring[2] = valuestring[1];
  2771.         yes = TRUE;
  2772.     } else commastring[2] = ' ';
  2773.  
  2774.     valuestring[ 2] = '0' + (value /   10000000);
  2775.     value %=   10000000;
  2776.     if (yes || valuestring[2] != '0')
  2777.     {   commastring[3] = valuestring[2];
  2778.         yes = TRUE;
  2779.     } else commastring[3] = ' ';
  2780.  
  2781.     valuestring[ 3] = '0' + (value /    1000000);
  2782.     value %=    1000000;
  2783.     if (yes || valuestring[3] != '0')
  2784.     {   commastring[4] = valuestring[3];
  2785.         yes = TRUE;
  2786.     } else
  2787.     {   commastring[4] = ' ';
  2788.         commastring[5] = ' ';
  2789.     }
  2790.  
  2791.     valuestring[ 4] = '0' + (value /     100000);
  2792.     value %=     100000;
  2793.     if (yes || valuestring[4] != '0')
  2794.     {   commastring[6] = valuestring[4];
  2795.         yes = TRUE;
  2796.     } else commastring[6] = ' ';
  2797.  
  2798.     valuestring[ 5] = '0' + (value /      10000);
  2799.     value %=      10000;
  2800.     if (yes || valuestring[5] != '0')
  2801.     {   commastring[7] = valuestring[5];
  2802.         yes = TRUE;
  2803.     } else commastring[7] = ' ';
  2804.  
  2805.     valuestring[ 6] = '0' + (value /       1000);
  2806.     value %=       1000;
  2807.     if (yes || valuestring[6] != '0')
  2808.     {   commastring[8] = valuestring[6];
  2809.         yes = TRUE;
  2810.     } else
  2811.     {   commastring[8] = ' ';
  2812.         commastring[9] = ' ';
  2813.     }
  2814.  
  2815.     valuestring[ 7] = '0' + (value /        100);
  2816.     value %=        100;
  2817.     if (yes || valuestring[7] != '0')
  2818.     {   commastring[10] = valuestring[7];
  2819.         yes = TRUE;
  2820.     } else commastring[10] = ' ';
  2821.  
  2822.     valuestring[ 8] = '0' + (value /         10);
  2823.     value %=         10;
  2824.     if (yes || valuestring[8] != '0')
  2825.     {   commastring[11] = valuestring[8];
  2826.         // yes = TRUE;
  2827.     } else commastring[11] = ' ';
  2828.  
  2829.     valuestring[ 9] = '0' +  value              ;
  2830.     commastring[12] = valuestring[9];
  2831. }
  2832.  
  2833. AGLOBAL ULONG SenderHookFunc(struct Hook *h, VOID *o, VOID *msg)
  2834. {   /* "When the hook is called, the data argument points to the 
  2835.     window object and message argument to the IntuiMessage." */
  2836.  
  2837.     UWORD code, qual;
  2838.  
  2839.     geta4(); // wait till here before doing anything
  2840.  
  2841.     code = ((struct IntuiMessage *) msg)->Code;
  2842.     qual = ((struct IntuiMessage *) msg)->Qualifier;
  2843.  
  2844.     switch(code)
  2845.     {
  2846.     case SCAN_HELP:
  2847.         helpabout();
  2848.     break;
  2849.     case SCAN_ESCAPE:
  2850.         if ((qual & IEQUALIFIER_LSHIFT) || (qual & IEQUALIFIER_RSHIFT))
  2851.         {   cleanexit(EXIT_SUCCESS);
  2852.         } else
  2853.         {   if (shared.function == 1)
  2854.             {   page = 11;
  2855.             } else
  2856.             {   assert(shared.function == 3);
  2857.                 page = 32;
  2858.         }   }
  2859.     break;
  2860.     case SCAN_F:
  2861.         ActivateLayoutGadget(sender_gadgets[GID_S_LY1], MainWindowPtr, NULL, (Object) sender_gadgets[GID_S_ST1]);
  2862.     break;
  2863.     case SCAN_L:
  2864.         ActivateLayoutGadget(sender_gadgets[GID_S_LY1], MainWindowPtr, NULL, (Object) sender_gadgets[GID_S_ST2]);
  2865.     break;
  2866.     case SCAN_C:
  2867.         ActivateLayoutGadget(sender_gadgets[GID_S_LY1], MainWindowPtr, NULL, (Object) sender_gadgets[GID_S_ST3]);
  2868.     break;
  2869.     case SCAN_P:
  2870.         ActivateLayoutGadget(sender_gadgets[GID_S_LY1], MainWindowPtr, NULL, (Object) sender_gadgets[GID_S_ST4]);
  2871.     break;
  2872.     case SCAN_D:
  2873.         ActivateLayoutGadget(sender_gadgets[GID_S_LY1], MainWindowPtr, NULL, (Object) sender_gadgets[GID_S_ST5]);
  2874.     break;
  2875.     case SCAN_E:
  2876.         ActivateLayoutGadget(sender_gadgets[GID_S_LY1], MainWindowPtr, NULL, (Object) sender_gadgets[GID_S_ST6]);
  2877.     break;
  2878.     default:
  2879.     break;
  2880.     }
  2881.  
  2882.     return(1);
  2883. }
  2884.  
  2885. AGLOBAL void addreactionnode(struct List* ListPtr, STRPTR text)
  2886. {   // This is only for single-column lists.
  2887.  
  2888.     struct ListBrowserNode* ListBrowserNodePtr;
  2889.  
  2890.     if (!(ListBrowserNodePtr = AllocListBrowserNode
  2891.     (   1,                   // columns,
  2892.         LBNCA_CopyText,      TRUE,
  2893.         LBNCA_Text,          text,
  2894.         TAG_END
  2895.     )))
  2896.     {   rq("Can't create ReAction listbrowser.gadget node(s)!");
  2897.     }
  2898.     AddTail(ListPtr, (struct Node *) ListBrowserNodePtr); // AddTail() has no return code
  2899. }
  2900.